Skip to content

Commit def7355

Browse files
committed
8356716: ZGC: Cleanup Uncommit Logic
Reviewed-by: eosterlund, jsikstro
1 parent 457d9de commit def7355

File tree

8 files changed

+395
-139
lines changed

8 files changed

+395
-139
lines changed

src/hotspot/share/gc/z/zMappedCache.cpp

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,7 @@ ZVirtualMemory ZMappedCache::remove_vmem(ZMappedCacheEntry* const entry, size_t
405405

406406
// Update statistics
407407
_size -= to_remove;
408-
_min = MIN2(_size, _min);
408+
_min_size_watermark = MIN2(_size, _min_size_watermark);
409409

410410
postcond(to_remove == vmem.size());
411411
return vmem;
@@ -558,7 +558,7 @@ ZMappedCache::ZMappedCache()
558558
: _tree(),
559559
_size_class_lists(),
560560
_size(0),
561-
_min(_size) {}
561+
_min_size_watermark(_size) {}
562562

563563
void ZMappedCache::insert(const ZVirtualMemory& vmem) {
564564
_size += vmem.size();
@@ -688,17 +688,15 @@ size_t ZMappedCache::remove_discontiguous(size_t size, ZArray<ZVirtualMemory>* o
688688
return remove_discontiguous_with_strategy<RemovalStrategy::SizeClasses>(size, out);
689689
}
690690

691-
size_t ZMappedCache::reset_min() {
692-
const size_t old_min = _min;
693-
694-
_min = _size;
695-
696-
return old_min;
691+
void ZMappedCache::reset_min_size_watermark() {
692+
_min_size_watermark = _size;
697693
}
698694

699-
size_t ZMappedCache::remove_from_min(size_t max_size, ZArray<ZVirtualMemory>* out) {
700-
const size_t size = MIN2(_min, max_size);
695+
size_t ZMappedCache::min_size_watermark() {
696+
return _min_size_watermark;
697+
}
701698

699+
size_t ZMappedCache::remove_for_uncommit(size_t size, ZArray<ZVirtualMemory>* out) {
702700
if (size == 0) {
703701
return 0;
704702
}

src/hotspot/share/gc/z/zMappedCache.hpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ class ZMappedCache {
9292
Tree _tree;
9393
SizeClassList _size_class_lists[NumSizeClasses];
9494
size_t _size;
95-
size_t _min;
95+
size_t _min_size_watermark;
9696

9797
static int size_class_index(size_t size);
9898
static int guaranteed_size_class_index(size_t size);
@@ -132,8 +132,10 @@ class ZMappedCache {
132132
ZVirtualMemory remove_contiguous_power_of_2(size_t min_size, size_t max_size);
133133
size_t remove_discontiguous(size_t size, ZArray<ZVirtualMemory>* out);
134134

135-
size_t reset_min();
136-
size_t remove_from_min(size_t max_size, ZArray<ZVirtualMemory>* out);
135+
// ZUncommitter support
136+
void reset_min_size_watermark();
137+
size_t min_size_watermark();
138+
size_t remove_for_uncommit(size_t size, ZArray<ZVirtualMemory>* out);
137139

138140
void print_on(outputStream* st) const;
139141
void print_extended_on(outputStream* st) const;

src/hotspot/share/gc/z/zPageAllocator.cpp

Lines changed: 1 addition & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -630,9 +630,6 @@ ZPartition::ZPartition(uint32_t numa_id, ZPageAllocator* page_allocator)
630630
_capacity(0),
631631
_claimed(0),
632632
_used(0),
633-
_last_commit(0.0),
634-
_last_uncommit(0.0),
635-
_to_uncommit(0),
636633
_numa_id(numa_id) {}
637634

638635
uint32_t ZPartition::numa_id() const {
@@ -650,9 +647,7 @@ size_t ZPartition::increase_capacity(size_t size) {
650647
// Update atomically since we have concurrent readers
651648
Atomic::add(&_capacity, increased);
652649

653-
_last_commit = os::elapsedTime();
654-
_last_uncommit = 0;
655-
_cache.reset_min();
650+
_uncommitter.cancel_uncommit_cycle();
656651
}
657652

658653
return increased;
@@ -787,101 +782,6 @@ bool ZPartition::claim_capacity_fast_medium(ZMemoryAllocation* allocation) {
787782
return true;
788783
}
789784

790-
size_t ZPartition::uncommit(uint64_t* timeout) {
791-
ZArray<ZVirtualMemory> flushed_vmems;
792-
size_t flushed = 0;
793-
794-
{
795-
// We need to join the suspendible thread set while manipulating capacity
796-
// and used, to make sure GC safepoints will have a consistent view.
797-
SuspendibleThreadSetJoiner sts_joiner;
798-
ZLocker<ZLock> locker(&_page_allocator->_lock);
799-
800-
const double now = os::elapsedTime();
801-
const double time_since_last_commit = std::floor(now - _last_commit);
802-
const double time_since_last_uncommit = std::floor(now - _last_uncommit);
803-
804-
if (time_since_last_commit < double(ZUncommitDelay)) {
805-
// We have committed within the delay, stop uncommitting.
806-
*timeout = uint64_t(double(ZUncommitDelay) - time_since_last_commit);
807-
return 0;
808-
}
809-
810-
// We flush out and uncommit chunks at a time (~0.8% of the max capacity,
811-
// but at least one granule and at most 256M), in case demand for memory
812-
// increases while we are uncommitting.
813-
const size_t limit_upper_bound = MAX2(ZGranuleSize, align_down(256 * M / ZNUMA::count(), ZGranuleSize));
814-
const size_t limit = MIN2(align_up(_current_max_capacity >> 7, ZGranuleSize), limit_upper_bound);
815-
816-
if (limit == 0) {
817-
// This may occur if the current max capacity for this partition is 0
818-
819-
// Set timeout to ZUncommitDelay
820-
*timeout = ZUncommitDelay;
821-
return 0;
822-
}
823-
824-
if (time_since_last_uncommit < double(ZUncommitDelay)) {
825-
// We are in the uncommit phase
826-
const size_t num_uncommits_left = _to_uncommit / limit;
827-
const double time_left = double(ZUncommitDelay) - time_since_last_uncommit;
828-
if (time_left < *timeout * num_uncommits_left) {
829-
// Running out of time, speed up.
830-
uint64_t new_timeout = uint64_t(std::floor(time_left / double(num_uncommits_left + 1)));
831-
*timeout = new_timeout;
832-
}
833-
} else {
834-
// We are about to start uncommitting
835-
_to_uncommit = _cache.reset_min();
836-
_last_uncommit = now;
837-
838-
const size_t split = _to_uncommit / limit + 1;
839-
uint64_t new_timeout = ZUncommitDelay / split;
840-
*timeout = new_timeout;
841-
}
842-
843-
// Never uncommit below min capacity.
844-
const size_t retain = MAX2(_used, _min_capacity);
845-
const size_t release = _capacity - retain;
846-
const size_t flush = MIN3(release, limit, _to_uncommit);
847-
848-
if (flush == 0) {
849-
// Nothing to flush
850-
return 0;
851-
}
852-
853-
// Flush memory from the mapped cache to uncommit
854-
flushed = _cache.remove_from_min(flush, &flushed_vmems);
855-
if (flushed == 0) {
856-
// Nothing flushed
857-
return 0;
858-
}
859-
860-
// Record flushed memory as claimed and how much we've flushed for this partition
861-
Atomic::add(&_claimed, flushed);
862-
_to_uncommit -= flushed;
863-
}
864-
865-
// Unmap and uncommit flushed memory
866-
for (const ZVirtualMemory vmem : flushed_vmems) {
867-
unmap_virtual(vmem);
868-
uncommit_physical(vmem);
869-
free_physical(vmem);
870-
free_virtual(vmem);
871-
}
872-
873-
{
874-
SuspendibleThreadSetJoiner sts_joiner;
875-
ZLocker<ZLock> locker(&_page_allocator->_lock);
876-
877-
// Adjust claimed and capacity to reflect the uncommit
878-
Atomic::sub(&_claimed, flushed);
879-
decrease_capacity(flushed, false /* set_max_capacity */);
880-
}
881-
882-
return flushed;
883-
}
884-
885785
void ZPartition::sort_segments_physical(const ZVirtualMemory& vmem) {
886786
verify_virtual_memory_association(vmem, true /* check_multi_partition */);
887787

src/hotspot/share/gc/z/zPageAllocator.hpp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ class ZWorkers;
5757
class ZPartition {
5858
friend class VMStructs;
5959
friend class ZPageAllocator;
60+
friend class ZUncommitter;
6061

6162
private:
6263
ZPageAllocator* const _page_allocator;
@@ -68,9 +69,6 @@ class ZPartition {
6869
volatile size_t _capacity;
6970
volatile size_t _claimed;
7071
size_t _used;
71-
double _last_commit;
72-
double _last_uncommit;
73-
size_t _to_uncommit;
7472
const uint32_t _numa_id;
7573

7674
const ZVirtualMemoryManager& virtual_memory_manager() const;
@@ -103,8 +101,6 @@ class ZPartition {
103101
bool claim_capacity(ZMemoryAllocation* allocation);
104102
bool claim_capacity_fast_medium(ZMemoryAllocation* allocation);
105103

106-
size_t uncommit(uint64_t* timeout);
107-
108104
void sort_segments_physical(const ZVirtualMemory& vmem);
109105

110106
void claim_physical(const ZVirtualMemory& vmem);

src/hotspot/share/gc/z/zPhysicalMemoryManager.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,11 @@ void ZPhysicalMemoryManager::try_enable_uncommit(size_t min_capacity, size_t max
113113
return;
114114
}
115115

116+
const size_t max_delay_without_overflow = std::numeric_limits<uint64_t>::max() / MILLIUNITS;
117+
if (ZUncommitDelay > max_delay_without_overflow) {
118+
FLAG_SET_ERGO(ZUncommitDelay, max_delay_without_overflow);
119+
}
120+
116121
log_info_p(gc, init)("Uncommit: Enabled");
117122
log_info_p(gc, init)("Uncommit Delay: %zus", ZUncommitDelay);
118123
}

0 commit comments

Comments
 (0)