Skip to content
Permalink
Browse files
8265136: ZGC: Expose GarbageCollectorMXBeans for both pauses and cycles
Reviewed-by: sspitsyn, ayang
  • Loading branch information
pliden committed Apr 20, 2021
1 parent f1d4ae6 commit 79798c656da20491ebaee3a6d26bad1bc2bc482a
Showing 9 changed files with 154 additions and 72 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 @@ class ZHeap {

// 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,16 +110,19 @@ 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);
}

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,29 +133,43 @@ 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() {
return _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,15 +43,18 @@ class ZServiceabilityMemoryPool : public CollectedMemoryPool {

class ZServiceabilityMemoryManager : public GCMemoryManager {
public:
ZServiceabilityMemoryManager(ZServiceabilityMemoryPool* pool);
ZServiceabilityMemoryManager(const char* name,
const char* end_message,
ZServiceabilityMemoryPool* pool);
};

class ZServiceability {
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 @@ class ZServiceability {
void initialize();

MemoryPool* memory_pool();
GCMemoryManager* memory_manager();
GCMemoryManager* cycle_memory_manager();
GCMemoryManager* pause_memory_manager();
ZServiceabilityCounters* counters();
};

@@ -74,8 +78,9 @@ class ZServiceabilityCycleTracer : public StackObj {

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 @@
* @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 static void main(String[] args) throws Exception {
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 static void main(String[] args) throws Exception {
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 static void main(String[] args) throws Exception {
}

final int minCycles = 5;
final int minPauses = minCycles * 3;

// Run GCs
for (int i = 0; i < minCycles; i++) {
@@ -162,17 +191,25 @@ public static void main(String[] args) throws Exception {
}

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
if (actualCycles < minCycles) {
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 comment on commit 79798c6

@openjdk-notifier
Copy link

@openjdk-notifier openjdk-notifier bot commented on 79798c6 Apr 20, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.