|
40 | 40 | #include "gc/g1/g1ConcurrentRefine.hpp" |
41 | 41 | #include "gc/g1/g1ConcurrentRefineThread.hpp" |
42 | 42 | #include "gc/g1/g1ConcurrentMarkThread.inline.hpp" |
| 43 | +#include "gc/g1/g1HeapEvaluationTask.hpp" |
| 44 | +#include "gc/g1/g1HeapSizingPolicy.hpp" // Include this first to avoid include cycle |
43 | 45 | #include "gc/g1/g1DirtyCardQueue.hpp" |
44 | 46 | #include "gc/g1/g1EvacStats.inline.hpp" |
45 | 47 | #include "gc/g1/g1FullCollector.hpp" |
46 | 48 | #include "gc/g1/g1GCCounters.hpp" |
47 | 49 | #include "gc/g1/g1GCParPhaseTimesTracker.hpp" |
48 | 50 | #include "gc/g1/g1GCPhaseTimes.hpp" |
49 | 51 | #include "gc/g1/g1GCPauseType.hpp" |
50 | | -#include "gc/g1/g1HeapSizingPolicy.hpp" |
51 | 52 | #include "gc/g1/g1HeapTransition.hpp" |
52 | 53 | #include "gc/g1/g1HeapVerifier.hpp" |
53 | 54 | #include "gc/g1/g1InitLogger.hpp" |
|
110 | 111 | #include "runtime/java.hpp" |
111 | 112 | #include "runtime/orderAccess.hpp" |
112 | 113 | #include "runtime/threadSMR.hpp" |
| 114 | +#include "runtime/vmOperations.hpp" |
113 | 115 | #include "runtime/vmThread.hpp" |
114 | 116 | #include "utilities/align.hpp" |
115 | 117 | #include "utilities/autoRestore.hpp" |
@@ -1169,6 +1171,24 @@ void G1CollectedHeap::shrink(size_t shrink_bytes) { |
1169 | 1171 | _verifier->verify_region_sets_optional(); |
1170 | 1172 | } |
1171 | 1173 |
|
| 1174 | +bool G1CollectedHeap::request_heap_shrink(size_t shrink_bytes) { |
| 1175 | + if (shrink_bytes == 0) { |
| 1176 | + return false; |
| 1177 | + } |
| 1178 | + |
| 1179 | + // Fast path: if we are already at a safepoint (e.g. called from the |
| 1180 | + // GC service thread) just do the work directly. |
| 1181 | + if (SafepointSynchronize::is_at_safepoint()) { |
| 1182 | + shrink(shrink_bytes); |
| 1183 | + return true; // we *did* something |
| 1184 | + } |
| 1185 | + |
| 1186 | + // Schedule a small VM-op so the work is done at the next safepoint |
| 1187 | + VM_G1ShrinkHeap op(this, shrink_bytes); |
| 1188 | + VMThread::execute(&op); |
| 1189 | + return true; // pages were at least *requested* to be released |
| 1190 | +} |
| 1191 | + |
1172 | 1192 | class OldRegionSetChecker : public HeapRegionSetChecker { |
1173 | 1193 | public: |
1174 | 1194 | void check_mt_safety() { |
@@ -1272,6 +1292,8 @@ G1CollectedHeap::G1CollectedHeap() : |
1272 | 1292 | _is_subject_to_discovery_cm(this), |
1273 | 1293 | _region_attr() { |
1274 | 1294 |
|
| 1295 | + _heap_evaluation_task = nullptr; |
| 1296 | + |
1275 | 1297 | _verifier = new G1HeapVerifier(this); |
1276 | 1298 |
|
1277 | 1299 | _allocator = new G1Allocator(this); |
@@ -1502,6 +1524,11 @@ jint G1CollectedHeap::initialize() { |
1502 | 1524 | _free_arena_memory_task = new G1MonotonicArenaFreeMemoryTask("Card Set Free Memory Task"); |
1503 | 1525 | _service_thread->register_task(_free_arena_memory_task); |
1504 | 1526 |
|
| 1527 | + if (G1UseTimeBasedHeapSizing) { |
| 1528 | + _heap_evaluation_task = new G1HeapEvaluationTask(this, _heap_sizing_policy); |
| 1529 | + _service_thread->register_task(_heap_evaluation_task); |
| 1530 | + } |
| 1531 | + |
1505 | 1532 | // Here we allocate the dummy HeapRegion that is required by the |
1506 | 1533 | // G1AllocRegion class. |
1507 | 1534 | HeapRegion* dummy_region = _hrm.get_dummy_region(); |
@@ -2954,6 +2981,7 @@ void G1CollectedHeap::retire_mutator_alloc_region(HeapRegion* alloc_region, |
2954 | 2981 | assert_heap_locked_or_at_safepoint(true /* should_be_vm_thread */); |
2955 | 2982 | assert(alloc_region->is_eden(), "all mutator alloc regions should be eden"); |
2956 | 2983 |
|
| 2984 | + alloc_region->record_activity(); // Update region access time |
2957 | 2985 | collection_set()->add_eden_region(alloc_region); |
2958 | 2986 | increase_used(allocated_bytes); |
2959 | 2987 | _eden.add_used_bytes(allocated_bytes); |
@@ -3162,3 +3190,18 @@ void G1CollectedHeap::finish_codecache_marking_cycle() { |
3162 | 3190 | CodeCache::on_gc_marking_cycle_finish(); |
3163 | 3191 | CodeCache::arm_all_nmethods(); |
3164 | 3192 | } |
| 3193 | + |
| 3194 | +bool G1CollectedHeap::check_region_for_uncommit(HeapRegion* hr) { |
| 3195 | + // First check if region is empty |
| 3196 | + if (!hr->is_empty()) { |
| 3197 | + log_trace(gc, heap)("Region %u not eligible for uncommit - not empty", hr->hrm_index()); |
| 3198 | + return false; |
| 3199 | + } |
| 3200 | + |
| 3201 | + bool should_uncommit = hr->should_uncommit(G1HeapSizingPolicy::uncommit_delay()); |
| 3202 | + |
| 3203 | + log_trace(gc, heap)("Region %u uncommit check: empty=%d should_uncommit=%d", |
| 3204 | + hr->hrm_index(), hr->is_empty(), should_uncommit); |
| 3205 | + |
| 3206 | + return should_uncommit; |
| 3207 | +} |
0 commit comments