8265136: ZGC: Expose GarbageCollectorMXBeans for both pauses and cycles

Reviewed-by: sspitsyn, ayang
This commit is contained in:
Per Liden 2021-04-20 07:53:43 +00:00
parent f1d4ae6cc9
commit 79798c656d
9 changed files with 155 additions and 73 deletions

@ -227,11 +227,16 @@ bool ZCollectedHeap::uses_stack_watermark_barrier() const {
}
GrowableArray<GCMemoryManager*> ZCollectedHeap::memory_managers() {
return GrowableArray<GCMemoryManager*>(1, 1, _heap.serviceability_memory_manager());
GrowableArray<GCMemoryManager*> memory_managers(2);
memory_managers.append(_heap.serviceability_cycle_memory_manager());
memory_managers.append(_heap.serviceability_pause_memory_manager());
return memory_managers;
}
GrowableArray<MemoryPool*> ZCollectedHeap::memory_pools() {
return GrowableArray<MemoryPool*>(1, 1, _heap.serviceability_memory_pool());
GrowableArray<MemoryPool*> memory_pools(1);
memory_pools.append(_heap.serviceability_memory_pool());
return memory_pools;
}
void ZCollectedHeap::object_iterate(ObjectClosure* cl) {

@ -455,8 +455,12 @@ void ZHeap::serviceability_initialize() {
_serviceability.initialize();
}
GCMemoryManager* ZHeap::serviceability_memory_manager() {
return _serviceability.memory_manager();
GCMemoryManager* ZHeap::serviceability_cycle_memory_manager() {
return _serviceability.cycle_memory_manager();
}
GCMemoryManager* ZHeap::serviceability_pause_memory_manager() {
return _serviceability.pause_memory_manager();
}
MemoryPool* ZHeap::serviceability_memory_pool() {

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -146,7 +146,8 @@ public:
// Serviceability
void serviceability_initialize();
GCMemoryManager* serviceability_memory_manager();
GCMemoryManager* serviceability_cycle_memory_manager();
GCMemoryManager* serviceability_pause_memory_manager();
MemoryPool* serviceability_memory_pool();
ZServiceabilityCounters* serviceability_counters();

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -110,8 +110,10 @@ MemoryUsage ZServiceabilityMemoryPool::get_memory_usage() {
return MemoryUsage(initial_size(), used, committed, max_size());
}
ZServiceabilityMemoryManager::ZServiceabilityMemoryManager(ZServiceabilityMemoryPool* pool)
: GCMemoryManager("ZGC", "end of major GC") {
ZServiceabilityMemoryManager::ZServiceabilityMemoryManager(const char* name,
const char* end_message,
ZServiceabilityMemoryPool* pool) :
GCMemoryManager(name, end_message) {
add_pool(pool);
}
@ -119,7 +121,8 @@ ZServiceability::ZServiceability(size_t min_capacity, size_t max_capacity) :
_min_capacity(min_capacity),
_max_capacity(max_capacity),
_memory_pool(_min_capacity, _max_capacity),
_memory_manager(&_memory_pool),
_cycle_memory_manager("ZGC Cycles", "end of GC cycle", &_memory_pool),
_pause_memory_manager("ZGC Pauses", "end of GC pause", &_memory_pool),
_counters(NULL) {}
void ZServiceability::initialize() {
@ -130,8 +133,12 @@ MemoryPool* ZServiceability::memory_pool() {
return &_memory_pool;
}
GCMemoryManager* ZServiceability::memory_manager() {
return &_memory_manager;
GCMemoryManager* ZServiceability::cycle_memory_manager() {
return &_cycle_memory_manager;
}
GCMemoryManager* ZServiceability::pause_memory_manager() {
return &_pause_memory_manager;
}
ZServiceabilityCounters* ZServiceability::counters() {
@ -139,20 +146,30 @@ ZServiceabilityCounters* ZServiceability::counters() {
}
ZServiceabilityCycleTracer::ZServiceabilityCycleTracer() :
_memory_manager_stats(ZHeap::heap()->serviceability_memory_manager(),
_memory_manager_stats(ZHeap::heap()->serviceability_cycle_memory_manager(),
ZCollectedHeap::heap()->gc_cause(),
true /* allMemoryPoolsAffected */,
true /* recordGCBeginTime */,
true /* recordPreGCUsage */,
true /* recordPeakUsage */,
true /* recordPostGCUsage */,
true /* recordAccumulatedGCTime */,
true /* recordGCEndTime */,
true /* countCollection */) {}
true /* allMemoryPoolsAffected */,
true /* recordGCBeginTime */,
true /* recordPreGCUsage */,
true /* recordPeakUsage */,
true /* recordPostGCUsage */,
true /* recordAccumulatedGCTime */,
true /* recordGCEndTime */,
true /* countCollection */) {}
ZServiceabilityPauseTracer::ZServiceabilityPauseTracer() :
_svc_gc_marker(SvcGCMarker::CONCURRENT),
_counters_stats(ZHeap::heap()->serviceability_counters()->collector_counters()) {}
_counters_stats(ZHeap::heap()->serviceability_counters()->collector_counters()),
_memory_manager_stats(ZHeap::heap()->serviceability_pause_memory_manager(),
ZCollectedHeap::heap()->gc_cause(),
true /* allMemoryPoolsAffected */,
true /* recordGCBeginTime */,
false /* recordPreGCUsage */,
false /* recordPeakUsage */,
false /* recordPostGCUsage */,
true /* recordAccumulatedGCTime */,
true /* recordGCEndTime */,
true /* countCollection */) {}
ZServiceabilityPauseTracer::~ZServiceabilityPauseTracer() {
ZHeap::heap()->serviceability_counters()->update_sizes();

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -43,7 +43,9 @@ public:
class ZServiceabilityMemoryManager : public GCMemoryManager {
public:
ZServiceabilityMemoryManager(ZServiceabilityMemoryPool* pool);
ZServiceabilityMemoryManager(const char* name,
const char* end_message,
ZServiceabilityMemoryPool* pool);
};
class ZServiceability {
@ -51,7 +53,8 @@ private:
const size_t _min_capacity;
const size_t _max_capacity;
ZServiceabilityMemoryPool _memory_pool;
ZServiceabilityMemoryManager _memory_manager;
ZServiceabilityMemoryManager _cycle_memory_manager;
ZServiceabilityMemoryManager _pause_memory_manager;
ZServiceabilityCounters* _counters;
public:
@ -60,7 +63,8 @@ public:
void initialize();
MemoryPool* memory_pool();
GCMemoryManager* memory_manager();
GCMemoryManager* cycle_memory_manager();
GCMemoryManager* pause_memory_manager();
ZServiceabilityCounters* counters();
};
@ -74,8 +78,9 @@ public:
class ZServiceabilityPauseTracer : public StackObj {
private:
SvcGCMarker _svc_gc_marker;
TraceCollectorStats _counters_stats;
SvcGCMarker _svc_gc_marker;
TraceCollectorStats _counters_stats;
TraceMemoryManagerStats _memory_manager_stats;
public:
ZServiceabilityPauseTracer();

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -28,7 +28,8 @@ package gc;
* @bug 7072527
* @summary JMM GC counters overcount in some cases
* @comment Shenandoah has "ExplicitGCInvokesConcurrent" on by default
* @requires !(vm.gc == "Shenandoah" & vm.opt.ExplicitGCInvokesConcurrent != false)
* @requires !(vm.gc == "Shenandoah" & vm.opt.ExplicitGCInvokesConcurrent != false)
* @requires vm.gc != "Z"
* @modules java.management
* @run main/othervm -Xlog:gc gc.TestFullGCCount
*/

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -53,6 +53,7 @@ public class TestGarbageCollectorMXBean {
final long initialCapacity = Long.parseLong(args[0]) * M;
final long maxCapacity = Long.parseLong(args[1]) * M;
final AtomicInteger cycles = new AtomicInteger();
final AtomicInteger pauses = new AtomicInteger();
final AtomicInteger errors = new AtomicInteger();
final NotificationListener listener = (Notification notification, Object ignored) -> {
@ -85,38 +86,65 @@ public class TestGarbageCollectorMXBean {
log(" MemoryUsageAfterGC: " + memoryUsageAfterGC);
log("");
if (name.equals("ZGC")) {
if (name.equals("ZGC Cycles")) {
cycles.incrementAndGet();
if (!action.equals("end of GC cycle")) {
log("ERROR: Action");
errors.incrementAndGet();
}
if (memoryUsageBeforeGC.getInit() != initialCapacity) {
log("ERROR: MemoryUsageBeforeGC.init");
errors.incrementAndGet();
}
if (memoryUsageBeforeGC.getUsed() > initialCapacity) {
log("ERROR: MemoryUsageBeforeGC.used");
errors.incrementAndGet();
}
if (memoryUsageBeforeGC.getCommitted() != initialCapacity) {
log("ERROR: MemoryUsageBeforeGC.committed");
errors.incrementAndGet();
}
if (memoryUsageBeforeGC.getMax() != maxCapacity) {
log("ERROR: MemoryUsageBeforeGC.max");
errors.incrementAndGet();
}
} else if (name.equals("ZGC Pauses")) {
pauses.incrementAndGet();
if (!action.equals("end of GC pause")) {
log("ERROR: Action");
errors.incrementAndGet();
}
if (memoryUsageBeforeGC.getInit() != 0) {
log("ERROR: MemoryUsageBeforeGC.init");
errors.incrementAndGet();
}
if (memoryUsageBeforeGC.getUsed() != 0) {
log("ERROR: MemoryUsageBeforeGC.used");
errors.incrementAndGet();
}
if (memoryUsageBeforeGC.getCommitted() != 0) {
log("ERROR: MemoryUsageBeforeGC.committed");
errors.incrementAndGet();
}
if (memoryUsageBeforeGC.getMax() != 0) {
log("ERROR: MemoryUsageBeforeGC.max");
errors.incrementAndGet();
}
} else {
log("ERROR: Name");
errors.incrementAndGet();
}
if (!action.equals("end of major GC")) {
log("ERROR: Action");
errors.incrementAndGet();
}
if (memoryUsageBeforeGC.getInit() != initialCapacity) {
log("ERROR: MemoryUsageBeforeGC.init");
errors.incrementAndGet();
}
if (memoryUsageBeforeGC.getUsed() > initialCapacity) {
log("ERROR: MemoryUsageBeforeGC.used");
errors.incrementAndGet();
}
if (memoryUsageBeforeGC.getCommitted() != initialCapacity) {
log("ERROR: MemoryUsageBeforeGC.committed");
errors.incrementAndGet();
}
if (memoryUsageBeforeGC.getMax() != maxCapacity) {
log("ERROR: MemoryUsageBeforeGC.max");
errors.incrementAndGet();
}
if (!cause.equals("System.gc()")) {
log("ERROR: Cause");
errors.incrementAndGet();
@ -143,6 +171,7 @@ public class TestGarbageCollectorMXBean {
}
final int minCycles = 5;
final int minPauses = minCycles * 3;
// Run GCs
for (int i = 0; i < minCycles; i++) {
@ -162,10 +191,13 @@ public class TestGarbageCollectorMXBean {
}
final int actualCycles = cycles.get();
final int actualPauses = pauses.get();
final int actualErrors = errors.get();
log(" minCycles: " + minCycles);
log(" minPauses: " + minPauses);
log("actualCycles: " + actualCycles);
log("actualPauses: " + actualPauses);
log("actualErrors: " + actualErrors);
// Verify number of cycle events
@ -173,6 +205,11 @@ public class TestGarbageCollectorMXBean {
throw new Exception("Unexpected cycles");
}
// Verify number of pause events
if (actualPauses < minPauses) {
throw new Exception("Unexpected pauses");
}
// Verify number of errors
if (actualErrors != 0) {
throw new Exception("Unexpected errors");

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -39,8 +39,10 @@ public class TestMemoryManagerMXBean {
}
public static void main(String[] args) throws Exception {
int zgcMemoryManagers = 0;
int zgcMemoryPools = 0;
int zgcCyclesMemoryManagers = 0;
int zgcPausesMemoryManagers = 0;
int zgcCyclesMemoryPools = 0;
int zgcPausesMemoryPools = 0;
for (final var memoryManager : ManagementFactory.getMemoryManagerMXBeans()) {
final var memoryManagerName = memoryManager.getName();
@ -48,8 +50,10 @@ public class TestMemoryManagerMXBean {
System.out.println("MemoryManager: " + memoryManagerName);
if (memoryManagerName.equals("ZGC")) {
zgcMemoryManagers++;
if (memoryManagerName.equals("ZGC Cycles")) {
zgcCyclesMemoryManagers++;
} else if (memoryManagerName.equals("ZGC Pauses")) {
zgcPausesMemoryManagers++;
}
for (final var memoryPoolName : memoryManager.getMemoryPoolNames()) {
@ -58,21 +62,29 @@ public class TestMemoryManagerMXBean {
System.out.println(" MemoryPool: " + memoryPoolName);
if (memoryPoolName.equals("ZHeap")) {
zgcMemoryPools++;
if (memoryManagerName.equals("ZGC Cycles")) {
zgcCyclesMemoryPools++;
} else if (memoryManagerName.equals("ZGC Pauses")) {
zgcPausesMemoryPools++;
}
}
}
if (zgcMemoryManagers != zgcMemoryPools) {
throw new Exception("MemoryManagers/MemoryPools mismatch");
}
}
if (zgcMemoryManagers != 1) {
throw new Exception("All MemoryManagers not found");
if (zgcCyclesMemoryManagers != 1) {
throw new Exception("Unexpected number of cycle MemoryManagers");
}
if (zgcMemoryPools != 1) {
throw new Exception("All MemoryPools not found");
if (zgcPausesMemoryManagers != 1) {
throw new Exception("Unexpected number of pause MemoryManagers");
}
if (zgcCyclesMemoryPools != 1) {
throw new Exception("Unexpected number of cycle MemoryPools");
}
if (zgcPausesMemoryPools != 1) {
throw new Exception("Unexpected number of pause MemoryPools");
}
}
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -42,7 +42,7 @@
* @author Mandy Chung
*
* @modules jdk.management
* @run main MemoryTest 1 1
* @run main MemoryTest 2 1
*/
/*