Skip to content

Commit

Permalink
8297247: Add GarbageCollectorMXBean for Remark and Cleanup pause time…
Browse files Browse the repository at this point in the history
… in G1

Reviewed-by: tschatzl, ayang
  • Loading branch information
linade authored and Thomas Schatzl committed Dec 6, 2022
1 parent e975418 commit f5ad515
Show file tree
Hide file tree
Showing 14 changed files with 185 additions and 24 deletions.
2 changes: 1 addition & 1 deletion src/hotspot/share/gc/g1/g1FullGCScope.cpp
Expand Up @@ -50,7 +50,7 @@ G1FullGCScope::G1FullGCScope(G1MonitoringSupport* monitoring_support,
_active(),
_tracer_mark(&_timer, _tracer),
_soft_refs(clear_soft, _g1h->soft_ref_policy()),
_monitoring_scope(monitoring_support, true /* full_gc */, true /* all_memory_pools_affected */),
_monitoring_scope(monitoring_support),
_heap_printer(_g1h),
_region_compaction_threshold(do_maximal_compaction ?
HeapRegion::GrainWords :
Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/share/gc/g1/g1FullGCScope.hpp
Expand Up @@ -55,7 +55,7 @@ class G1FullGCScope : public StackObj {
IsGCActiveMark _active;
G1FullGCJFRTracerMark _tracer_mark;
ClearedAllSoftRefs _soft_refs;
G1MonitoringScope _monitoring_scope;
G1FullGCMonitoringScope _monitoring_scope;
G1HeapPrinterMark _heap_printer;
size_t _region_compaction_threshold;

Expand Down
35 changes: 31 additions & 4 deletions src/hotspot/share/gc/g1/g1MonitoringSupport.cpp
Expand Up @@ -90,6 +90,7 @@ G1MonitoringSupport::G1MonitoringSupport(G1CollectedHeap* g1h) :
_g1h(g1h),
_incremental_memory_manager("G1 Young Generation", "end of minor GC"),
_full_gc_memory_manager("G1 Old Generation", "end of major GC"),
_conc_gc_memory_manager("G1 Concurrent GC", "end of concurrent GC pause"),
_eden_space_pool(NULL),
_survivor_space_pool(NULL),
_old_gen_pool(NULL),
Expand Down Expand Up @@ -199,6 +200,8 @@ void G1MonitoringSupport::initialize_serviceability() {
_full_gc_memory_manager.add_pool(_survivor_space_pool);
_full_gc_memory_manager.add_pool(_old_gen_pool);

_conc_gc_memory_manager.add_pool(_old_gen_pool);

_incremental_memory_manager.add_pool(_eden_space_pool);
_incremental_memory_manager.add_pool(_survivor_space_pool);
_incremental_memory_manager.add_pool(_old_gen_pool, false /* always_affected_by_gc */);
Expand All @@ -210,9 +213,10 @@ MemoryUsage G1MonitoringSupport::memory_usage() {
}

GrowableArray<GCMemoryManager*> G1MonitoringSupport::memory_managers() {
GrowableArray<GCMemoryManager*> memory_managers(2);
GrowableArray<GCMemoryManager*> memory_managers(3);
memory_managers.append(&_incremental_memory_manager);
memory_managers.append(&_full_gc_memory_manager);
memory_managers.append(&_conc_gc_memory_manager);
return memory_managers;
}

Expand Down Expand Up @@ -344,10 +348,13 @@ MemoryUsage G1MonitoringSupport::old_gen_memory_usage(size_t initial_size, size_
max_size);
}

G1MonitoringScope::G1MonitoringScope(G1MonitoringSupport* monitoring_support, bool full_gc, bool all_memory_pools_affected) :
G1MonitoringScope::G1MonitoringScope(G1MonitoringSupport* monitoring_support,
CollectorCounters* collection_counters,
GCMemoryManager* gc_memory_manager,
bool all_memory_pools_affected) :
_monitoring_support(monitoring_support),
_tcs(full_gc ? monitoring_support->_full_collection_counters : monitoring_support->_incremental_collection_counters),
_tms(full_gc ? &monitoring_support->_full_gc_memory_manager : &monitoring_support->_incremental_memory_manager,
_tcs(collection_counters),
_tms(gc_memory_manager,
G1CollectedHeap::heap()->gc_cause(), all_memory_pools_affected) {
}

Expand All @@ -356,3 +363,23 @@ G1MonitoringScope::~G1MonitoringScope() {
// Needs to be called after updating pool sizes.
MemoryService::track_memory_usage();
}

G1YoungGCMonitoringScope::G1YoungGCMonitoringScope(G1MonitoringSupport* monitoring_support,
bool all_memory_pools_affected) :
G1MonitoringScope(monitoring_support,
monitoring_support->_incremental_collection_counters,
&monitoring_support->_incremental_memory_manager,
all_memory_pools_affected) {
}

G1FullGCMonitoringScope::G1FullGCMonitoringScope(G1MonitoringSupport* monitoring_support) :
G1MonitoringScope(monitoring_support,
monitoring_support->_full_collection_counters,
&monitoring_support->_full_gc_memory_manager) {
}

G1ConcGCMonitoringScope::G1ConcGCMonitoringScope(G1MonitoringSupport* monitoring_support) :
G1MonitoringScope(monitoring_support,
monitoring_support->_conc_collection_counters,
&monitoring_support->_conc_gc_memory_manager) {
}
30 changes: 23 additions & 7 deletions src/hotspot/share/gc/g1/g1MonitoringSupport.hpp
Expand Up @@ -121,13 +121,16 @@ class MemoryPool;

class G1MonitoringSupport : public CHeapObj<mtGC> {
friend class VMStructs;
friend class G1MonitoringScope;
friend class G1YoungGCMonitoringScope;
friend class G1FullGCMonitoringScope;
friend class G1ConcGCMonitoringScope;

G1CollectedHeap* _g1h;

// java.lang.management MemoryManager and MemoryPool support
GCMemoryManager _incremental_memory_manager;
GCMemoryManager _full_gc_memory_manager;
GCMemoryManager _conc_gc_memory_manager;

MemoryPool* _eden_space_pool;
MemoryPool* _survivor_space_pool;
Expand Down Expand Up @@ -210,10 +213,6 @@ class G1MonitoringSupport : public CHeapObj<mtGC> {

void update_eden_size();

CollectorCounters* conc_collection_counters() {
return _conc_collection_counters;
}

// Monitoring support used by
// MemoryService
// jstat counters
Expand Down Expand Up @@ -241,9 +240,26 @@ class G1MonitoringScope : public StackObj {
G1MonitoringSupport* _monitoring_support;
TraceCollectorStats _tcs;
TraceMemoryManagerStats _tms;
public:
G1MonitoringScope(G1MonitoringSupport* monitoring_support, bool full_gc, bool all_memory_pools_affected);
protected:
G1MonitoringScope(G1MonitoringSupport* monitoring_support,
CollectorCounters* collection_counters,
GCMemoryManager* gc_memory_manager,
bool all_memory_pools_affected = true);
~G1MonitoringScope();
};

class G1YoungGCMonitoringScope : public G1MonitoringScope {
public:
G1YoungGCMonitoringScope(G1MonitoringSupport* monitoring_support, bool all_memory_pools_affected);
};

class G1FullGCMonitoringScope : public G1MonitoringScope {
public:
G1FullGCMonitoringScope(G1MonitoringSupport* monitoring_support);
};

class G1ConcGCMonitoringScope : public G1MonitoringScope {
public:
G1ConcGCMonitoringScope(G1MonitoringSupport* monitoring_support);
};
#endif // SHARE_GC_G1_G1MONITORINGSUPPORT_HPP
2 changes: 1 addition & 1 deletion src/hotspot/share/gc/g1/g1VMOperations.cpp
Expand Up @@ -172,7 +172,7 @@ void VM_G1PauseConcurrent::doit() {
GCTraceTimePauseTimer timer(_message, g1h->concurrent_mark()->gc_timer_cm());
GCTraceTimeDriver t(&logger, &timer);

TraceCollectorStats tcs(g1h->monitoring_support()->conc_collection_counters());
G1ConcGCMonitoringScope monitoring_scope(g1h->monitoring_support());
SvcGCMarker sgcm(SvcGCMarker::CONCURRENT);
IsGCActiveMark x;

Expand Down
5 changes: 2 additions & 3 deletions src/hotspot/share/gc/g1/g1YoungCollector.cpp
Expand Up @@ -1056,9 +1056,8 @@ void G1YoungCollector::collect() {
// JFR
G1YoungGCJFRTracerMark jtm(gc_timer_stw(), gc_tracer_stw(), _gc_cause);
// JStat/MXBeans
G1MonitoringScope ms(monitoring_support(),
false /* full_gc */,
collector_state()->in_mixed_phase() /* all_memory_pools_affected */);
G1YoungGCMonitoringScope ms(monitoring_support(),
collector_state()->in_mixed_phase() /* all_memory_pools_affected */);
// Create the heap printer before internal pause timing to have
// heap information printed as last part of detailed GC log.
G1HeapPrinterMark hpm(_g1h);
Expand Down
3 changes: 2 additions & 1 deletion test/hotspot/jtreg/gc/TestMemoryMXBeansAndPoolsPresence.java
Expand Up @@ -96,7 +96,8 @@ public static void main(String[] args) {
switch (args[0]) {
case "G1":
test(new GCBeanDescription("G1 Young Generation", new String[] {"G1 Eden Space", "G1 Survivor Space", "G1 Old Gen"}),
new GCBeanDescription("G1 Old Generation", new String[] {"G1 Eden Space", "G1 Survivor Space", "G1 Old Gen"}));
new GCBeanDescription("G1 Old Generation", new String[] {"G1 Eden Space", "G1 Survivor Space", "G1 Old Gen"}),
new GCBeanDescription("G1 Concurrent GC", new String[] {"G1 Old Gen"}));
break;
case "Parallel":
test(new GCBeanDescription("PS Scavenge", new String[] {"PS Eden Space", "PS Survivor Space"}),
Expand Down
74 changes: 74 additions & 0 deletions test/hotspot/jtreg/gc/g1/TestRemarkCleanupMXBean.java
@@ -0,0 +1,74 @@
/*
* Copyright (c) 2022, Alibaba Group Holding Limited. 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/

package gc.g1;

/*
* @test TestRemarkCleanupMXBean
* @bug 8297247
* @summary Test that Remark and Cleanup are correctly reported by
* a GarbageCollectorMXBean
* @requires vm.gc.G1
* @library /test/lib /
* @build jdk.test.whitebox.WhiteBox
* @modules java.base/jdk.internal.misc
* java.management
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
* @run main/othervm -XX:+UseG1GC -Xlog:gc
* -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
* gc.g1.TestRemarkCleanupMXBean
*/

import java.lang.management.GarbageCollectorMXBean;
import java.lang.management.ManagementFactory;
import jdk.test.whitebox.WhiteBox;
import jdk.test.whitebox.gc.GC;
import gc.testlibrary.g1.MixedGCProvoker;

public class TestRemarkCleanupMXBean {
public static void main(String[] args) throws Exception {
GarbageCollectorMXBean g1ConcGCBean = null;
String expectedName = "G1 Concurrent GC";
for (GarbageCollectorMXBean bean : ManagementFactory.getGarbageCollectorMXBeans()) {
if (expectedName.equals(bean.getName())) {
g1ConcGCBean = bean;
break;
}
}
if (g1ConcGCBean == null) {
throw new RuntimeException("Unable to find GC bean: " + expectedName);
}

long before = g1ConcGCBean.getCollectionCount();
MixedGCProvoker.provokeConcMarkCycle();
long after = g1ConcGCBean.getCollectionCount();

if (after >= before + 2) { // Must report a Remark and a Cleanup
System.out.println(g1ConcGCBean.getName() + " reports a difference " +
after + " - " + before + " = " + (after - before));
} else {
throw new RuntimeException("Remark or Cleanup not reported by " +
g1ConcGCBean.getName());
}
}
}
Expand Up @@ -104,6 +104,10 @@ public void handleNotification(Notification n, Object o) {
if ("end of GC cycle".equals(info.getGcAction())) {
gcCount++;
}
} else if (info.getGcName().startsWith("G1")) {
if ("end of minor GC".equals(info.getGcAction())) {
gcCount++;
}
} else {
gcCount++;
}
Expand Down
13 changes: 10 additions & 3 deletions test/hotspot/jtreg/gc/testlibrary/g1/MixedGCProvoker.java
Expand Up @@ -73,13 +73,20 @@ public static void allocateOldObjects(
}

/**
* Provoke at least one mixed gc by starting a marking cycle, waiting for its end and triggering two GCs.
* @param liveOldObjects The objects supposed to survive this marking cycle.
* Provoke a concurrent mark cycle, and wait for it to end.
*/
public static void provokeMixedGC(List<byte[]> liveOldObjects) {
public static void provokeConcMarkCycle() {
Helpers.waitTillCMCFinished(getWhiteBox(), 10);
getWhiteBox().g1StartConcMarkCycle();
Helpers.waitTillCMCFinished(getWhiteBox(), 10);
}

/**
* Provoke at least one mixed gc by starting a marking cycle, waiting for its end and triggering two GCs.
* @param liveOldObjects The objects supposed to survive this marking cycle.
*/
public static void provokeMixedGC(List<byte[]> liveOldObjects) {
provokeConcMarkCycle();
getWhiteBox().youngGC(); // the "Prepare Mixed" gc
getWhiteBox().youngGC(); // the "Mixed" gc

Expand Down
Expand Up @@ -29,7 +29,11 @@
* @requires vm.opt.ExplicitGCInvokesConcurrent == null | vm.opt.ExplicitGCInvokesConcurrent == false
* @modules java.management/sun.management
* jdk.management
* @run main/othervm -Xms64m -Xmx64m GarbageCollectionNotificationContentTest
* @library /test/lib /test/hotspot/jtreg
* @build jdk.test.whitebox.WhiteBox
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
* -Xms64m -Xmx64m GarbageCollectionNotificationContentTest
*/

import java.util.*;
Expand All @@ -42,6 +46,8 @@
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.lang.reflect.Field;
import jdk.test.whitebox.gc.GC;
import gc.testlibrary.g1.MixedGCProvoker;

public class GarbageCollectionNotificationContentTest {
private static HashMap<String,GarbageCollectionNotificationInfo> listenerInvoked
Expand Down Expand Up @@ -100,6 +106,10 @@ public static void main(String[] args) throws Exception {
for(int i = 0; i<10000000; i++) {
data[i%32] = new int[8];
}
// Trigger G1's concurrent mark
if (GC.G1.isSelected()) {
MixedGCProvoker.provokeConcMarkCycle();
}
int wakeup = 0;
synchronized(synchronizer) {
while(count != number) {
Expand Down
Expand Up @@ -29,7 +29,11 @@
* @requires vm.opt.ExplicitGCInvokesConcurrent == null | vm.opt.ExplicitGCInvokesConcurrent == false
* @modules java.management/sun.management
* jdk.management
* @run main/othervm GarbageCollectionNotificationTest
* @library /test/lib /test/hotspot/jtreg
* @build jdk.test.whitebox.WhiteBox
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
* GarbageCollectionNotificationTest
*/

import java.util.*;
Expand All @@ -42,6 +46,8 @@
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.lang.reflect.Field;
import jdk.test.whitebox.gc.GC;
import gc.testlibrary.g1.MixedGCProvoker;

public class GarbageCollectionNotificationTest {
private static HashMap<String,Boolean> listenerInvoked = new HashMap<String,Boolean>();
Expand Down Expand Up @@ -99,6 +105,10 @@ public static void main(String[] args) throws Exception {
for(int i = 0; i<100000000; i++) {
data[i%32] = new int[8];
}
// Trigger G1's concurrent mark
if (GC.G1.isSelected()) {
MixedGCProvoker.provokeConcMarkCycle();
}
int wakeup = 0;
synchronized(synchronizer) {
while(count != number) {
Expand Down
14 changes: 13 additions & 1 deletion test/jdk/java/lang/management/MemoryMXBean/MemoryTest.java
Expand Up @@ -26,7 +26,7 @@
* @bug 4530538
* @summary Basic unit test of MemoryMXBean.getMemoryPools() and
* MemoryMXBean.getMemoryManager().
* @requires vm.gc != "Z" & vm.gc != "Shenandoah"
* @requires vm.gc != "Z" & vm.gc != "Shenandoah" & !vm.gc.G1
* @author Mandy Chung
*
* @modules jdk.management
Expand All @@ -45,6 +45,18 @@
* @run main MemoryTest 2 1
*/

/*
* @test
* @bug 4530538
* @summary Basic unit test of MemoryMXBean.getMemoryPools() and
* MemoryMXBean.getMemoryManager().
* @requires vm.gc.G1
* @author Mandy Chung
*
* @modules jdk.management
* @run main MemoryTest 3 3
*/

/*
* NOTE: This expected result is hardcoded in this test and this test
* will be affected if the heap memory layout is changed in
Expand Down
1 change: 1 addition & 0 deletions test/lib/jdk/test/lib/jfr/GCHelper.java
Expand Up @@ -175,6 +175,7 @@ public static List<RecordedEvent> removeFirstAndLastGC(List<RecordedEvent> event

// old GarbageCollectionMXBeans.
beanCollectorTypes.put("G1 Old Generation", false);
beanCollectorTypes.put("G1 Concurrent GC", false);
beanCollectorTypes.put("PS MarkSweep", false);
beanCollectorTypes.put("MarkSweepCompact", false);

Expand Down

1 comment on commit f5ad515

@openjdk-notifier
Copy link

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.