src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp

Print this page
rev 6757 : 8051973: Eager reclaim leaves marks of marked but reclaimed objects on the next bitmap
Summary: Eager reclaim also needs to clear marks of eagerly reclaimed regions if they have already been marked during concurrent mark.
Reviewed-by:


6519 
6520 class G1FreeHumongousRegionClosure : public HeapRegionClosure {
6521  private:
6522   FreeRegionList* _free_region_list;
6523   HeapRegionSet* _proxy_set;
6524   HeapRegionSetCount _humongous_regions_removed;
6525   size_t _freed_bytes;
6526  public:
6527 
6528   G1FreeHumongousRegionClosure(FreeRegionList* free_region_list) :
6529     _free_region_list(free_region_list), _humongous_regions_removed(), _freed_bytes(0) {
6530   }
6531 
6532   virtual bool doHeapRegion(HeapRegion* r) {
6533     if (!r->startsHumongous()) {
6534       return false;
6535     }
6536 
6537     G1CollectedHeap* g1h = G1CollectedHeap::heap();
6538 



6539     // The following checks whether the humongous object is live are sufficient.
6540     // The main additional check (in addition to having a reference from the roots
6541     // or the young gen) is whether the humongous object has a remembered set entry.
6542     //
6543     // A humongous object cannot be live if there is no remembered set for it
6544     // because:
6545     // - there can be no references from within humongous starts regions referencing
6546     // the object because we never allocate other objects into them.
6547     // (I.e. there are no intra-region references that may be missed by the
6548     // remembered set)
6549     // - as soon there is a remembered set entry to the humongous starts region
6550     // (i.e. it has "escaped" to an old object) this remembered set entry will stay
6551     // until the end of a concurrent mark.
6552     //
6553     // It is not required to check whether the object has been found dead by marking
6554     // or not, in fact it would prevent reclamation within a concurrent cycle, as
6555     // all objects allocated during that time are considered live.
6556     // SATB marking is even more conservative than the remembered set.
6557     // So if at this point in the collection there is no remembered set entry,
6558     // nobody has a reference to it.
6559     // At the start of collection we flush all refinement logs, and remembered sets
6560     // are completely up-to-date wrt to references to the humongous object.
6561     //
6562     // Other implementation considerations:
6563     // - never consider object arrays: while they are a valid target, they have not
6564     // been observed to be used as temporary objects.
6565     // - they would also pose considerable effort for cleaning up the the remembered
6566     // sets.
6567     // While this cleanup is not strictly necessary to be done (or done instantly),
6568     // given that their occurrence is very low, this saves us this additional
6569     // complexity.
6570     uint region_idx = r->hrs_index();
6571     if (g1h->humongous_is_live(region_idx) ||
6572         g1h->humongous_region_is_always_live(region_idx)) {
6573 
6574       if (G1TraceReclaimDeadHumongousObjectsAtYoungGC) {
6575         gclog_or_tty->print_cr("Live humongous %d region %d with remset "SIZE_FORMAT" code roots "SIZE_FORMAT" is dead-bitmap %d live-other %d obj array %d",
6576                                r->isHumongous(),
6577                                region_idx,
6578                                r->rem_set()->occupied(),
6579                                r->rem_set()->strong_code_roots_list_length(),
6580                                g1h->mark_in_progress() && !g1h->g1_policy()->during_initial_mark_pause(),
6581                                g1h->humongous_is_live(region_idx),
6582                                oop(r->bottom())->is_objArray()
6583                               );
6584       }
6585 
6586       return false;
6587     }
6588 
6589     guarantee(!((oop)(r->bottom()))->is_objArray(),
6590               err_msg("Eagerly reclaiming object arrays is not supported, but the object "PTR_FORMAT" is.",
6591                       r->bottom()));
6592 
6593     if (G1TraceReclaimDeadHumongousObjectsAtYoungGC) {
6594       gclog_or_tty->print_cr("Reclaim humongous region %d start "PTR_FORMAT" region %d length "UINT32_FORMAT" with remset "SIZE_FORMAT" code roots "SIZE_FORMAT" is dead-bitmap %d live-other %d obj array %d",
6595                              r->isHumongous(),
6596                              r->bottom(),
6597                              region_idx,
6598                              r->region_num(),
6599                              r->rem_set()->occupied(),
6600                              r->rem_set()->strong_code_roots_list_length(),
6601                              g1h->mark_in_progress() && !g1h->g1_policy()->during_initial_mark_pause(),
6602                              g1h->humongous_is_live(region_idx),
6603                              oop(r->bottom())->is_objArray()
6604                             );
6605     }




6606     _freed_bytes += r->used();
6607     r->set_containing_set(NULL);
6608     _humongous_regions_removed.increment(1u, r->capacity());
6609     g1h->free_humongous_region(r, _free_region_list, false);
6610 
6611     return false;
6612   }
6613 
6614   HeapRegionSetCount& humongous_free_count() {
6615     return _humongous_regions_removed;
6616   }
6617 
6618   size_t bytes_freed() const {
6619     return _freed_bytes;
6620   }
6621 
6622   size_t humongous_reclaimed() const {
6623     return _humongous_regions_removed.length();
6624   }
6625 };




6519 
6520 class G1FreeHumongousRegionClosure : public HeapRegionClosure {
6521  private:
6522   FreeRegionList* _free_region_list;
6523   HeapRegionSet* _proxy_set;
6524   HeapRegionSetCount _humongous_regions_removed;
6525   size_t _freed_bytes;
6526  public:
6527 
6528   G1FreeHumongousRegionClosure(FreeRegionList* free_region_list) :
6529     _free_region_list(free_region_list), _humongous_regions_removed(), _freed_bytes(0) {
6530   }
6531 
6532   virtual bool doHeapRegion(HeapRegion* r) {
6533     if (!r->startsHumongous()) {
6534       return false;
6535     }
6536 
6537     G1CollectedHeap* g1h = G1CollectedHeap::heap();
6538 
6539     oop obj = (oop)r->bottom();
6540     CMBitMap* next_bitmap = g1h->concurrent_mark()->nextMarkBitMap();
6541 
6542     // The following checks whether the humongous object is live are sufficient.
6543     // The main additional check (in addition to having a reference from the roots
6544     // or the young gen) is whether the humongous object has a remembered set entry.
6545     //
6546     // A humongous object cannot be live if there is no remembered set for it
6547     // because:
6548     // - there can be no references from within humongous starts regions referencing
6549     // the object because we never allocate other objects into them.
6550     // (I.e. there are no intra-region references that may be missed by the
6551     // remembered set)
6552     // - as soon there is a remembered set entry to the humongous starts region
6553     // (i.e. it has "escaped" to an old object) this remembered set entry will stay
6554     // until the end of a concurrent mark.
6555     //
6556     // It is not required to check whether the object has been found dead by marking
6557     // or not, in fact it would prevent reclamation within a concurrent cycle, as
6558     // all objects allocated during that time are considered live.
6559     // SATB marking is even more conservative than the remembered set.
6560     // So if at this point in the collection there is no remembered set entry,
6561     // nobody has a reference to it.
6562     // At the start of collection we flush all refinement logs, and remembered sets
6563     // are completely up-to-date wrt to references to the humongous object.
6564     //
6565     // Other implementation considerations:
6566     // - never consider object arrays: while they are a valid target, they have not
6567     // been observed to be used as temporary objects.
6568     // - they would also pose considerable effort for cleaning up the the remembered
6569     // sets.
6570     // While this cleanup is not strictly necessary to be done (or done instantly),
6571     // given that their occurrence is very low, this saves us this additional
6572     // complexity.
6573     uint region_idx = r->hrs_index();
6574     if (g1h->humongous_is_live(region_idx) ||
6575         g1h->humongous_region_is_always_live(region_idx)) {
6576 
6577       if (G1TraceReclaimDeadHumongousObjectsAtYoungGC) {
6578         gclog_or_tty->print_cr("Live humongous %d region %d with remset "SIZE_FORMAT" code roots "SIZE_FORMAT" is marked %d live-other %d obj array %d",
6579                                r->isHumongous(),
6580                                region_idx,
6581                                r->rem_set()->occupied(),
6582                                r->rem_set()->strong_code_roots_list_length(),
6583                                next_bitmap->isMarked(r->bottom()),
6584                                g1h->humongous_is_live(region_idx),
6585                                obj->is_objArray()
6586                               );
6587       }
6588 
6589       return false;
6590     }
6591 
6592     guarantee(!obj->is_objArray(),
6593               err_msg("Eagerly reclaiming object arrays is not supported, but the object "PTR_FORMAT" is.",
6594                       r->bottom()));
6595 
6596     if (G1TraceReclaimDeadHumongousObjectsAtYoungGC) {
6597       gclog_or_tty->print_cr("Reclaim humongous region %d start "PTR_FORMAT" region %d length "UINT32_FORMAT" with remset "SIZE_FORMAT" code roots "SIZE_FORMAT" is marked %d live-other %d obj array %d",
6598                              r->isHumongous(),
6599                              r->bottom(),
6600                              region_idx,
6601                              r->region_num(),
6602                              r->rem_set()->occupied(),
6603                              r->rem_set()->strong_code_roots_list_length(),
6604                              next_bitmap->isMarked(r->bottom()),
6605                              g1h->humongous_is_live(region_idx),
6606                              obj->is_objArray()
6607                             );
6608     }
6609     // Need to clear mark bit of the humongous object if already set.
6610     if (next_bitmap->isMarked(r->bottom())) {
6611       next_bitmap->clear(r->bottom());
6612     }
6613     _freed_bytes += r->used();
6614     r->set_containing_set(NULL);
6615     _humongous_regions_removed.increment(1u, r->capacity());
6616     g1h->free_humongous_region(r, _free_region_list, false);
6617 
6618     return false;
6619   }
6620 
6621   HeapRegionSetCount& humongous_free_count() {
6622     return _humongous_regions_removed;
6623   }
6624 
6625   size_t bytes_freed() const {
6626     return _freed_bytes;
6627   }
6628 
6629   size_t humongous_reclaimed() const {
6630     return _humongous_regions_removed.length();
6631   }
6632 };