25
25
*/
26
26
27
27
#include " precompiled.hpp"
28
- #include " memory/allocation.hpp"
29
- #include " memory/universe.hpp"
28
+
29
+ #include " cds/archiveHeapWriter.hpp"
30
+ #include " classfile/systemDictionary.hpp"
31
+ #include " code/codeCache.hpp"
30
32
31
33
#include " gc/shared/classUnloadingContext.hpp"
32
34
#include " gc/shared/fullGCForwarding.hpp"
42
44
#include " gc/shenandoah/heuristics/shenandoahYoungHeuristics.hpp"
43
45
#include " gc/shenandoah/shenandoahAllocRequest.hpp"
44
46
#include " gc/shenandoah/shenandoahBarrierSet.hpp"
45
- #include " gc/shenandoah/shenandoahClosures.inline .hpp"
47
+ #include " gc/shenandoah/shenandoahCodeRoots .hpp"
46
48
#include " gc/shenandoah/shenandoahCollectionSet.hpp"
47
49
#include " gc/shenandoah/shenandoahCollectorPolicy.hpp"
48
50
#include " gc/shenandoah/shenandoahConcurrentMark.hpp"
49
- #include " gc/shenandoah/shenandoahMarkingContext.inline.hpp"
50
51
#include " gc/shenandoah/shenandoahControlThread.hpp"
52
+ #include " gc/shenandoah/shenandoahClosures.inline.hpp"
51
53
#include " gc/shenandoah/shenandoahFreeSet.hpp"
52
54
#include " gc/shenandoah/shenandoahGenerationalEvacuationTask.hpp"
53
55
#include " gc/shenandoah/shenandoahGenerationalHeap.hpp"
54
56
#include " gc/shenandoah/shenandoahGlobalGeneration.hpp"
55
- #include " gc/shenandoah/shenandoahPhaseTimings.hpp"
56
57
#include " gc/shenandoah/shenandoahHeap.inline.hpp"
57
58
#include " gc/shenandoah/shenandoahHeapRegionClosures.hpp"
58
59
#include " gc/shenandoah/shenandoahHeapRegion.inline.hpp"
65
66
#include " gc/shenandoah/shenandoahPacer.inline.hpp"
66
67
#include " gc/shenandoah/shenandoahPadding.hpp"
67
68
#include " gc/shenandoah/shenandoahParallelCleaning.inline.hpp"
69
+ #include " gc/shenandoah/shenandoahPhaseTimings.hpp"
68
70
#include " gc/shenandoah/shenandoahReferenceProcessor.hpp"
69
71
#include " gc/shenandoah/shenandoahRootProcessor.inline.hpp"
70
72
#include " gc/shenandoah/shenandoahScanRemembered.inline.hpp"
71
73
#include " gc/shenandoah/shenandoahSTWMark.hpp"
74
+ #include " gc/shenandoah/shenandoahUncommitThread.hpp"
72
75
#include " gc/shenandoah/shenandoahUtils.hpp"
73
76
#include " gc/shenandoah/shenandoahVerifier.hpp"
74
- #include " gc/shenandoah/shenandoahCodeRoots.hpp"
75
77
#include " gc/shenandoah/shenandoahVMOperations.hpp"
76
78
#include " gc/shenandoah/shenandoahWorkGroup.hpp"
77
79
#include " gc/shenandoah/shenandoahWorkerPolicy.hpp"
78
80
#include " gc/shenandoah/shenandoahYoungGeneration.hpp"
79
81
#include " gc/shenandoah/mode/shenandoahGenerationalMode.hpp"
80
82
#include " gc/shenandoah/mode/shenandoahPassiveMode.hpp"
81
83
#include " gc/shenandoah/mode/shenandoahSATBMode.hpp"
82
- #include " utilities/globalDefinitions.hpp"
83
84
84
85
#if INCLUDE_JFR
85
86
#include " gc/shenandoah/shenandoahJfrSupport.hpp"
86
87
#endif
87
88
88
- #include " cds/archiveHeapWriter.hpp"
89
- #include " classfile/systemDictionary.hpp"
90
- #include " code/codeCache.hpp"
89
+
90
+ #include " memory/allocation.hpp"
91
91
#include " memory/classLoaderMetaspace.hpp"
92
92
#include " memory/metaspaceUtils.hpp"
93
+ #include " memory/universe.hpp"
93
94
#include " nmt/mallocTracker.hpp"
94
95
#include " nmt/memTracker.hpp"
95
96
#include " oops/compressedOops.inline.hpp"
102
103
#include " runtime/safepointMechanism.hpp"
103
104
#include " runtime/stackWatermarkSet.hpp"
104
105
#include " runtime/vmThread.hpp"
106
+ #include " utilities/globalDefinitions.hpp"
105
107
#include " utilities/events.hpp"
106
108
#include " utilities/powerOfTwo.hpp"
107
109
@@ -459,6 +461,10 @@ jint ShenandoahHeap::initialize() {
459
461
460
462
initialize_controller ();
461
463
464
+ if (ShenandoahUncommit) {
465
+ _uncommit_thread = new ShenandoahUncommitThread (this );
466
+ }
467
+
462
468
print_init_logger ();
463
469
464
470
FullGCForwarding::initialize (_heap_region);
@@ -530,6 +536,7 @@ ShenandoahHeap::ShenandoahHeap(ShenandoahCollectorPolicy* policy) :
530
536
_update_refs_iterator(this ),
531
537
_global_generation(nullptr ),
532
538
_control_thread(nullptr ),
539
+ _uncommit_thread(nullptr ),
533
540
_young_generation(nullptr ),
534
541
_old_generation(nullptr ),
535
542
_shenandoah_policy(policy),
@@ -800,60 +807,15 @@ bool ShenandoahHeap::is_in(const void* p) const {
800
807
}
801
808
}
802
809
803
- void ShenandoahHeap::maybe_uncommit (double shrink_before, size_t shrink_until) {
804
- assert (ShenandoahUncommit, " should be enabled" );
805
-
806
- // Determine if there is work to do. This avoids taking heap lock if there is
807
- // no work available, avoids spamming logs with superfluous logging messages,
808
- // and minimises the amount of work while locks are taken.
809
-
810
- if (committed () <= shrink_until) return ;
811
-
812
- bool has_work = false ;
813
- for (size_t i = 0 ; i < num_regions (); i++) {
814
- ShenandoahHeapRegion* r = get_region (i);
815
- if (r->is_empty_committed () && (r->empty_time () < shrink_before)) {
816
- has_work = true ;
817
- break ;
818
- }
819
- }
820
-
821
- if (has_work) {
822
- static const char * msg = " Concurrent uncommit" ;
823
- ShenandoahConcurrentPhase gcPhase (msg, ShenandoahPhaseTimings::conc_uncommit, true /* log_heap_usage */ );
824
- EventMark em (" %s" , msg);
825
-
826
- op_uncommit (shrink_before, shrink_until);
810
+ void ShenandoahHeap::notify_soft_max_changed () {
811
+ if (_uncommit_thread != nullptr ) {
812
+ _uncommit_thread->notify_soft_max_changed ();
827
813
}
828
814
}
829
815
830
- void ShenandoahHeap::op_uncommit (double shrink_before, size_t shrink_until) {
831
- assert (ShenandoahUncommit, " should be enabled" );
832
-
833
- // Application allocates from the beginning of the heap, and GC allocates at
834
- // the end of it. It is more efficient to uncommit from the end, so that applications
835
- // could enjoy the near committed regions. GC allocations are much less frequent,
836
- // and therefore can accept the committing costs.
837
-
838
- size_t count = 0 ;
839
- for (size_t i = num_regions (); i > 0 ; i--) { // care about size_t underflow
840
- ShenandoahHeapRegion* r = get_region (i - 1 );
841
- if (r->is_empty_committed () && (r->empty_time () < shrink_before)) {
842
- ShenandoahHeapLocker locker (lock ());
843
- if (r->is_empty_committed ()) {
844
- if (committed () < shrink_until + ShenandoahHeapRegion::region_size_bytes ()) {
845
- break ;
846
- }
847
-
848
- r->make_uncommitted ();
849
- count++;
850
- }
851
- }
852
- SpinPause (); // allow allocators to take the lock
853
- }
854
-
855
- if (count > 0 ) {
856
- notify_heap_changed ();
816
+ void ShenandoahHeap::notify_explicit_gc_requested () {
817
+ if (_uncommit_thread != nullptr ) {
818
+ _uncommit_thread->notify_explicit_gc_requested ();
857
819
}
858
820
}
859
821
@@ -1507,6 +1469,10 @@ void ShenandoahHeap::gc_threads_do(ThreadClosure* tcl) const {
1507
1469
tcl->do_thread (_control_thread);
1508
1470
}
1509
1471
1472
+ if (_uncommit_thread != nullptr ) {
1473
+ tcl->do_thread (_uncommit_thread);
1474
+ }
1475
+
1510
1476
workers ()->threads_do (tcl);
1511
1477
if (_safepoint_workers != nullptr ) {
1512
1478
_safepoint_workers->threads_do (tcl);
@@ -2094,6 +2060,11 @@ void ShenandoahHeap::stop() {
2094
2060
2095
2061
// Step 3. Wait until GC worker exits normally.
2096
2062
control_thread ()->stop ();
2063
+
2064
+ // Stop 4. Shutdown uncommit thread.
2065
+ if (_uncommit_thread != nullptr ) {
2066
+ _uncommit_thread->stop ();
2067
+ }
2097
2068
}
2098
2069
2099
2070
void ShenandoahHeap::stw_unload_classes (bool full_gc) {
@@ -2521,7 +2492,7 @@ bool ShenandoahHeap::uncommit_bitmap_slice(ShenandoahHeapRegion *r) {
2521
2492
2522
2493
if (is_bitmap_slice_committed (r, true )) {
2523
2494
// Some other region from the group is still committed, meaning the bitmap
2524
- // slice is should stay committed, exit right away.
2495
+ // slice should stay committed, exit right away.
2525
2496
return true ;
2526
2497
}
2527
2498
@@ -2535,6 +2506,27 @@ bool ShenandoahHeap::uncommit_bitmap_slice(ShenandoahHeapRegion *r) {
2535
2506
return true ;
2536
2507
}
2537
2508
2509
+ void ShenandoahHeap::forbid_uncommit () {
2510
+ if (_uncommit_thread != nullptr ) {
2511
+ _uncommit_thread->forbid_uncommit ();
2512
+ }
2513
+ }
2514
+
2515
+ void ShenandoahHeap::allow_uncommit () {
2516
+ if (_uncommit_thread != nullptr ) {
2517
+ _uncommit_thread->allow_uncommit ();
2518
+ }
2519
+ }
2520
+
2521
+ #ifdef ASSERT
2522
+ bool ShenandoahHeap::is_uncommit_in_progress () {
2523
+ if (_uncommit_thread != nullptr ) {
2524
+ return _uncommit_thread->is_uncommit_in_progress ();
2525
+ }
2526
+ return false ;
2527
+ }
2528
+ #endif
2529
+
2538
2530
void ShenandoahHeap::safepoint_synchronize_begin () {
2539
2531
StackWatermarkSet::safepoint_synchronize_begin ();
2540
2532
SuspendibleThreadSet::synchronize ();
0 commit comments