|
1 | 1 | /*
|
2 |
| - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. |
| 2 | + * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved. |
3 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
4 | 4 | *
|
5 | 5 | * This code is free software; you can redistribute it and/or modify it
|
|
32 | 32 | #include "gc/g1/g1FullGCCompactTask.hpp"
|
33 | 33 | #include "gc/g1/g1FullGCMarker.inline.hpp"
|
34 | 34 | #include "gc/g1/g1FullGCMarkTask.hpp"
|
35 |
| -#include "gc/g1/g1FullGCPrepareTask.hpp" |
| 35 | +#include "gc/g1/g1FullGCPrepareTask.inline.hpp" |
36 | 36 | #include "gc/g1/g1FullGCScope.hpp"
|
37 | 37 | #include "gc/g1/g1OopClosures.hpp"
|
38 | 38 | #include "gc/g1/g1Policy.hpp"
|
@@ -297,14 +297,67 @@ void G1FullCollector::phase1_mark_live_objects() {
|
297 | 297 | }
|
298 | 298 |
|
299 | 299 | void G1FullCollector::phase2_prepare_compaction() {
|
300 |
| - GCTraceTime(Info, gc, phases) info("Phase 2: Prepare for compaction", scope()->timer()); |
| 300 | + GCTraceTime(Info, gc, phases) info("Phase 2: Prepare compaction", scope()->timer()); |
| 301 | + |
| 302 | + phase2a_determine_worklists(); |
| 303 | + |
| 304 | + bool has_free_compaction_targets = phase2b_forward_oops(); |
| 305 | + |
| 306 | + // Try to avoid OOM immediately after Full GC in case there are no free regions |
| 307 | + // left after determining the result locations (i.e. this phase). Prepare to |
| 308 | + // maximally compact the tail regions of the compaction queues serially. |
| 309 | + if (!has_free_compaction_targets) { |
| 310 | + phase2c_prepare_serial_compaction(); |
| 311 | + } |
| 312 | +} |
| 313 | + |
| 314 | +void G1FullCollector::phase2a_determine_worklists() { |
| 315 | + GCTraceTime(Debug, gc, phases) debug("Phase 2: Determine work lists", scope()->timer()); |
| 316 | + |
| 317 | + G1DetermineCompactionQueueClosure cl(this); |
| 318 | + _heap->heap_region_iterate(&cl); |
| 319 | +} |
| 320 | + |
| 321 | +bool G1FullCollector::phase2b_forward_oops() { |
| 322 | + GCTraceTime(Debug, gc, phases) debug("Phase 2: Prepare parallel compaction", scope()->timer()); |
| 323 | + |
301 | 324 | G1FullGCPrepareTask task(this);
|
302 | 325 | run_task(&task);
|
303 | 326 |
|
304 |
| - // To avoid OOM when there is memory left. |
305 |
| - if (!task.has_freed_regions()) { |
306 |
| - task.prepare_serial_compaction(); |
| 327 | + return task.has_free_compaction_targets(); |
| 328 | +} |
| 329 | + |
| 330 | +void G1FullCollector::phase2c_prepare_serial_compaction() { |
| 331 | + GCTraceTime(Debug, gc, phases) debug("Phase 2: Prepare serial compaction", scope()->timer()); |
| 332 | + // At this point we know that after parallel compaction there will be no |
| 333 | + // completely free regions. That means that the last region of |
| 334 | + // all compaction queues still have data in them. We try to compact |
| 335 | + // these regions in serial to avoid a premature OOM when the mutator wants |
| 336 | + // to allocate the first eden region after gc. |
| 337 | + for (uint i = 0; i < workers(); i++) { |
| 338 | + G1FullGCCompactionPoint* cp = compaction_point(i); |
| 339 | + if (cp->has_regions()) { |
| 340 | + serial_compaction_point()->add(cp->remove_last()); |
| 341 | + } |
| 342 | + } |
| 343 | + |
| 344 | + // Update the forwarding information for the regions in the serial |
| 345 | + // compaction point. |
| 346 | + G1FullGCCompactionPoint* cp = serial_compaction_point(); |
| 347 | + for (GrowableArrayIterator<HeapRegion*> it = cp->regions()->begin(); it != cp->regions()->end(); ++it) { |
| 348 | + HeapRegion* current = *it; |
| 349 | + if (!cp->is_initialized()) { |
| 350 | + // Initialize the compaction point. Nothing more is needed for the first heap region |
| 351 | + // since it is already prepared for compaction. |
| 352 | + cp->initialize(current, false); |
| 353 | + } else { |
| 354 | + assert(!current->is_humongous(), "Should be no humongous regions in compaction queue"); |
| 355 | + G1SerialRePrepareClosure re_prepare(cp, current); |
| 356 | + current->set_compaction_top(current->bottom()); |
| 357 | + current->apply_to_marked_objects(mark_bitmap(), &re_prepare); |
| 358 | + } |
307 | 359 | }
|
| 360 | + cp->update(); |
308 | 361 | }
|
309 | 362 |
|
310 | 363 | void G1FullCollector::phase3_adjust_pointers() {
|
|
0 commit comments