diff --git a/src/share/vm/gc/g1/g1CollectedHeap.cpp b/src/share/vm/gc/g1/g1CollectedHeap.cpp
--- a/src/share/vm/gc/g1/g1CollectedHeap.cpp
+++ b/src/share/vm/gc/g1/g1CollectedHeap.cpp
@@ -3484,6 +3484,7 @@
     _evacuation_failed = true;
   }
 
+  verify_size(obj);
   _evacuation_failed_info_array[worker_id].register_copy_failure(obj->size());
   _preserved_marks_set.get(worker_id)->push_if_necessary(obj, m);
 }
diff --git a/src/share/vm/gc/g1/g1CollectedHeap.hpp b/src/share/vm/gc/g1/g1CollectedHeap.hpp
--- a/src/share/vm/gc/g1/g1CollectedHeap.hpp
+++ b/src/share/vm/gc/g1/g1CollectedHeap.hpp
@@ -1490,6 +1490,12 @@
 public:
   size_t pending_card_num();
 
+  inline void verify_size(narrowOop* ref);
+
+  inline void verify_size(oop* ref);
+
+  inline void verify_size(oop p);
+
 protected:
   size_t _max_heap_capacity;
 };
diff --git a/src/share/vm/gc/g1/g1CollectedHeap.inline.hpp b/src/share/vm/gc/g1/g1CollectedHeap.inline.hpp
--- a/src/share/vm/gc/g1/g1CollectedHeap.inline.hpp
+++ b/src/share/vm/gc/g1/g1CollectedHeap.inline.hpp
@@ -303,4 +303,36 @@
   }
 }
 
+
+void G1CollectedHeap::verify_size(oop p) {
+  if ((size_t)p->size() > 400000) { // TEST: the problematic oop has larger than this.
+    HeapRegion* r = heap_region_containing(p);
+    if (r->is_young() || r-> is_old()) {
+      HeapWord* addr = (HeapWord*)p + p->size();
+      bool is_in = addr <= r->end();
+
+      bool is_dead = is_obj_dead(p, r);
+      bool is_ill = is_obj_ill(p, r);
+      bool is_from_mark = !p->is_gc_marked() && !r->is_archive();
+      Klass* k = p->klass();
+      Symbol* name = k->name();
+
+      guarantee(is_in, "verify_size, %s, %s, %s, region=" PTR_FORMAT " \'oop(" PTR_FORMAT ", %s) + oop->size(" SIZE_FORMAT
+                        ")\' (" PTR_FORMAT ") exceeds region->end(" PTR_FORMAT ", %s) age=%u",
+                        is_dead?"dead":"-", is_ill?"ill":"-", is_from_mark?"from mark":"-", p2i(r),
+                        p2i(p), name->as_C_string(), (size_t)p->size()*sizeof(HeapWord), p2i(addr), p2i(r->end()), r->get_type_str(), p->age());
+    }
+  }
+}
+
+inline void G1CollectedHeap::verify_size(narrowOop* ref) {
+  oop p = oopDesc::load_decode_heap_oop(ref);
+  verify_size(p);
+}
+
+inline void G1CollectedHeap::verify_size(oop* ref) {
+  oop p = oopDesc::load_decode_heap_oop(ref);
+  // Don't test for this case
+}
+
 #endif // SHARE_VM_GC_G1_G1COLLECTEDHEAP_INLINE_HPP
diff --git a/src/share/vm/gc/g1/g1EvacFailure.cpp b/src/share/vm/gc/g1/g1EvacFailure.cpp
--- a/src/share/vm/gc/g1/g1EvacFailure.cpp
+++ b/src/share/vm/gc/g1/g1EvacFailure.cpp
@@ -100,7 +100,19 @@
     if (obj->is_forwarded() && obj->forwardee() == obj) {
       // The object failed to move.
 
+      size_t obj_size1 = obj->size();
+      HeapWord* end = obj_addr + obj_size1;
+      if (_hr->is_young()) {
+        guarantee(_hr->is_in(end), "BEFORE, object is out of region(" PTR_FORMAT ")", p2i(end));
+      }
+
       zap_dead_objects(_last_forwarded_object_end, obj_addr);
+
+      size_t obj_size = obj->size();
+      if (obj_size1 != obj_size) {
+        guarantee(false, "object size is changed from (" SIZE_FORMAT ") to (" SIZE_FORMAT ")", obj_size1, obj_size);
+      }
+
       // We consider all objects that we find self-forwarded to be
       // live. What we'll do is that we'll update the prev marking
       // info so that they are all under PTAMS and explicitly marked.
@@ -120,7 +132,7 @@
         // we'll leave them over NTAMS.
         _cm->grayRoot(obj, _hr);
       }
-      size_t obj_size = obj->size();
+      //size_t obj_size = obj->size();
 
       _marked_bytes += (obj_size * HeapWordSize);
       PreservedMarks::init_forwarded_mark(obj);
@@ -140,6 +152,11 @@
       obj->oop_iterate(_update_rset_cl);
 
       HeapWord* obj_end = obj_addr + obj_size;
+
+      if (_hr->is_young()) {
+        guarantee(_hr->is_in(obj_end), "object is out of region(" PTR_FORMAT ")", p2i(obj_end));
+      }
+
       _last_forwarded_object_end = obj_end;
       _hr->cross_threshold(obj_addr, obj_end);
     }
diff --git a/src/share/vm/gc/g1/g1OopClosures.inline.hpp b/src/share/vm/gc/g1/g1OopClosures.inline.hpp
--- a/src/share/vm/gc/g1/g1OopClosures.inline.hpp
+++ b/src/share/vm/gc/g1/g1OopClosures.inline.hpp
@@ -67,9 +67,12 @@
   T heap_oop = oopDesc::load_heap_oop(p);
 
   if (!oopDesc::is_null(heap_oop)) {
+    _g1->verify_size(p);
+
     oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
     const InCSetState state = _g1->in_cset_state(obj);
     if (state.is_in_cset()) {
+
       // We're not going to even bother checking whether the object is
       // already forwarded or not, as this usually causes an immediate
       // stall. We'll try to prefetch the object (for write, given that
diff --git a/src/share/vm/gc/g1/g1ParScanThreadState.inline.hpp b/src/share/vm/gc/g1/g1ParScanThreadState.inline.hpp
--- a/src/share/vm/gc/g1/g1ParScanThreadState.inline.hpp
+++ b/src/share/vm/gc/g1/g1ParScanThreadState.inline.hpp
@@ -60,6 +60,7 @@
 
 template <class T> inline void G1ParScanThreadState::push_on_queue(T* ref) {
   assert(verify_ref(ref), "sanity");
+  _g1h->verify_size(ref);
   _refs->push(ref);
 }
 
@@ -115,6 +116,7 @@
 template <class T> inline void G1ParScanThreadState::deal_with_reference(T* ref_to_scan) {
   if (!has_partial_array_mask(ref_to_scan)) {
     HeapRegion* r = _g1h->heap_region_containing(ref_to_scan);
+    _g1h->verify_size(ref_to_scan);
     do_oop_evac(ref_to_scan, r);
   } else {
     do_oop_partial_array((oop*)ref_to_scan);
