< prev index next >

src/hotspot/share/gc/g1/g1YoungCollector.cpp

Print this page

 311       // live objects are missed by the marking process.  Objects
 312       // allocated after the start of concurrent marking don't need to
 313       // be scanned.
 314       //
 315       // * An object must not be reclaimed if it is on the concurrent
 316       // mark stack.  Objects allocated after the start of concurrent
 317       // marking are never pushed on the mark stack.
 318       //
 319       // Nominating only objects allocated after the start of concurrent
 320       // marking is sufficient to meet both constraints.  This may miss
 321       // some objects that satisfy the constraints, but the marking data
 322       // structures don't support efficiently performing the needed
 323       // additional tests or scrubbing of the mark stack.
 324       //
 325       // We handle humongous objects specially, because frequent allocation and
 326       // dropping of large binary blobs is an important use case for eager reclaim,
 327       // and this special handling increases needed headroom.
 328       // It also helps with G1 allocating humongous objects as old generation
 329       // objects although they might also die quite quickly.
 330       //
 331       // TypeArray objects are allowed to be reclaimed even if allocated before

 332       // the start of concurrent mark.  For this we rely on mark stack insertion
 333       // to exclude is_typeArray() objects, preventing reclaiming an object
 334       // that is in the mark stack.  We also rely on the metadata for
 335       // such objects to be built-in and so ensured to be kept live.
 336       //
 337       // Non-typeArrays that were allocated before marking are excluded from
 338       // eager reclaim during marking.  One issue is the problem described
 339       // above with scrubbing the mark stack, but there is also a problem
 340       // causing these humongous objects being collected incorrectly:
 341       //
 342       // E.g. if the mutator is running, we may have objects o1 and o2 in the same
 343       // region, where o1 has already been scanned and o2 is only reachable by
 344       // the candidate object h, which is humongous.
 345       //
 346       // If the mutator read the reference to o2 from h and installed it into o1,
 347       // no remembered set entry would be created for keeping alive o2, as o1 and
 348       // o2 are in the same region.  Object h might be reclaimed by the next
 349       // garbage collection. o1 still has the reference to o2, but since o1 had
 350       // already been scanned we do not detect o2 to be still live and reclaim it.
 351       //
 352       // There is another minor problem with non-typeArray regions being the source
 353       // of remembered set entries in other region's remembered sets.  There are
 354       // two cases: first, the remembered set entry is in a Free region after reclaim.
 355       // We handle this case by ignoring these cards during merging the remembered
 356       // sets.
 357       //
 358       // Second, there may be cases where eagerly reclaimed regions were already
 359       // reallocated.  This may cause scanning of these outdated remembered set
 360       // entries, containing some objects. But apart from extra work this does
 361       // not cause correctness issues.

 362       // There is no difference between scanning cards covering an effectively
 363       // dead humongous object vs. some other objects in reallocated regions.
 364       //
 365       // TAMSes are only reset after completing the entire mark cycle, during
 366       // bitmap clearing. It is worth to not wait until then, and allow reclamation
 367       // outside of actual (concurrent) SATB marking.
 368       // This also applies to the concurrent start pause - we only set
 369       // mark_in_progress() at the end of that GC: no mutator is running that can
 370       // sneakily install a new reference to the potentially reclaimed humongous
 371       // object.
 372       // During the concurrent start pause the situation described above where we
 373       // miss a reference can not happen. No mutator is modifying the object
 374       // graph to install such an overlooked reference.
 375       //
 376       // After the pause, having reclaimed h, obviously the mutator can't fetch
 377       // the reference from h any more.
 378       if (!obj->is_typeArray()) {

 379         // All regions that were allocated before marking have a TAMS != bottom.
 380         bool allocated_before_mark_start = region->bottom() != _g1h->concurrent_mark()->top_at_mark_start(region);
 381         bool mark_in_progress = _g1h->collector_state()->is_in_marking();
 382 
 383         if (allocated_before_mark_start && mark_in_progress) {
 384           return false;
 385         }
 386       }
 387       return _g1h->is_potential_eager_reclaim_candidate(region);
 388     }
 389 
 390   public:
 391     G1PrepareRegionsClosure(G1CollectedHeap* g1h, G1PrepareEvacuationTask* parent_task) :
 392       _g1h(g1h),
 393       _parent_task(parent_task),
 394       _worker_humongous_total(0),
 395       _worker_humongous_candidates(0),
 396       _humongous_card_set_stats() { }
 397 
 398     ~G1PrepareRegionsClosure() {

 311       // live objects are missed by the marking process.  Objects
 312       // allocated after the start of concurrent marking don't need to
 313       // be scanned.
 314       //
 315       // * An object must not be reclaimed if it is on the concurrent
 316       // mark stack.  Objects allocated after the start of concurrent
 317       // marking are never pushed on the mark stack.
 318       //
 319       // Nominating only objects allocated after the start of concurrent
 320       // marking is sufficient to meet both constraints.  This may miss
 321       // some objects that satisfy the constraints, but the marking data
 322       // structures don't support efficiently performing the needed
 323       // additional tests or scrubbing of the mark stack.
 324       //
 325       // We handle humongous objects specially, because frequent allocation and
 326       // dropping of large binary blobs is an important use case for eager reclaim,
 327       // and this special handling increases needed headroom.
 328       // It also helps with G1 allocating humongous objects as old generation
 329       // objects although they might also die quite quickly.
 330       //
 331       // Humongous objects without oops (typeArrays, flatArrays without oops in
 332       // its elements) are allowed to be reclaimed even if allocated before
 333       // the start of concurrent mark.  For this we rely on mark stack insertion
 334       // to exclude them, preventing reclaiming an object
 335       // that is in the mark stack.  That code also ensures that metadata (klass)
 336       // is kept live.
 337       //
 338       // Other humongous objects that were allocated before marking are excluded from
 339       // eager reclaim during marking.  One issue is the problem described
 340       // above with scrubbing the mark stack, but there is also a problem
 341       // causing these humongous objects being collected incorrectly:
 342       //
 343       // E.g. if the mutator is running, we may have objects o1 and o2 in the same
 344       // region, where o1 has already been scanned and o2 is only reachable by
 345       // the candidate object h, which is humongous.
 346       //
 347       // If the mutator read the reference to o2 from h and installed it into o1,
 348       // no remembered set entry would be created for keeping alive o2, as o1 and
 349       // o2 are in the same region.  Object h might be reclaimed by the next
 350       // garbage collection. o1 still has the reference to o2, but since o1 had
 351       // already been scanned we do not detect o2 to be still live and reclaim it.
 352       //
 353       // There is another minor problem with these humongous objects with oops being
 354       // the source of remembered set entries in other region's remembered sets.
 355       // There are two cases: first, the remembered set entry is in a Free region
 356       // after reclaim.  We handle this case by ignoring these cards during merging
 357       // the remembered sets.
 358       //
 359       // Second, there may be cases where regions previously containing eagerly
 360       // reclaimed objects were already allocated into again.
 361       // This may cause scanning of these outdated remembered set entries,
 362       // containing some objects. But apart from extra work this does not cause
 363       // correctness issues.
 364       // There is no difference between scanning cards covering an effectively
 365       // dead humongous object vs. some other objects in reallocated regions.
 366       //
 367       // TAMSes are only reset after completing the entire mark cycle, during
 368       // bitmap clearing. It is worth to not wait until then, and allow reclamation
 369       // outside of actual (concurrent) SATB marking.
 370       // This also applies to the concurrent start pause - we only set
 371       // mark_in_progress() at the end of that GC: no mutator is running that can
 372       // sneakily install a new reference to the potentially reclaimed humongous
 373       // object.
 374       // During the concurrent start pause the situation described above where we
 375       // miss a reference can not happen. No mutator is modifying the object
 376       // graph to install such an overlooked reference.
 377       //
 378       // After the pause, having reclaimed h, obviously the mutator can't fetch
 379       // the reference from h any more.
 380       bool marked_immediately = _g1h->can_be_marked_through_immediately(obj);
 381       if (!marked_immediately) {
 382         // All regions that were allocated before marking have a TAMS != bottom.
 383         bool allocated_before_mark_start = region->bottom() != _g1h->concurrent_mark()->top_at_mark_start(region);
 384         bool mark_in_progress = _g1h->collector_state()->is_in_marking();
 385 
 386         if (allocated_before_mark_start && mark_in_progress) {
 387           return false;
 388         }
 389       }
 390       return _g1h->is_potential_eager_reclaim_candidate(region);
 391     }
 392 
 393   public:
 394     G1PrepareRegionsClosure(G1CollectedHeap* g1h, G1PrepareEvacuationTask* parent_task) :
 395       _g1h(g1h),
 396       _parent_task(parent_task),
 397       _worker_humongous_total(0),
 398       _worker_humongous_candidates(0),
 399       _humongous_card_set_stats() { }
 400 
 401     ~G1PrepareRegionsClosure() {
< prev index next >