diff --git a/src/hotspot/share/jfr/metadata/metadata.xml b/src/hotspot/share/jfr/metadata/metadata.xml
index d04e0825d28..f2a7b802528 100644
--- a/src/hotspot/share/jfr/metadata/metadata.xml
+++ b/src/hotspot/share/jfr/metadata/metadata.xml
@@ -260,6 +260,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/hotspot/share/jfr/periodic/jfrPeriodic.cpp b/src/hotspot/share/jfr/periodic/jfrPeriodic.cpp
index 7ff3b29c289..1730e429bab 100644
--- a/src/hotspot/share/jfr/periodic/jfrPeriodic.cpp
+++ b/src/hotspot/share/jfr/periodic/jfrPeriodic.cpp
@@ -65,6 +65,7 @@
#include "runtime/vm_version.hpp"
#include "services/classLoadingService.hpp"
#include "services/management.hpp"
+#include "services/memoryPool.hpp"
#include "services/threadService.hpp"
#include "utilities/exceptions.hpp"
#include "utilities/globalDefinitions.hpp"
@@ -526,6 +527,37 @@ TRACE_REQUEST_FUNC(JavaThreadStatistics) {
event.commit();
}
+TRACE_REQUEST_FUNC(GCHeapMemoryUsage) {
+ MemoryUsage usage = Universe::heap()->memory_usage();
+ EventGCHeapMemoryUsage event(UNTIMED);
+ event.set_used(usage.used());
+ event.set_committed(usage.committed());
+ event.set_max(usage.max_size());
+ event.set_starttime(timestamp());
+ event.set_endtime(timestamp());
+ event.commit();
+}
+
+TRACE_REQUEST_FUNC(GCHeapMemoryPoolUsage) {
+ ResourceMark mark;
+ GrowableArray pools = Universe::heap()->memory_pools();
+ for (int i = 0; i < pools.length(); i++) {
+ MemoryPool* pool = pools.at(i);
+ if (pool->is_heap()) {
+ MemoryUsage usage = pool->get_memory_usage();
+ EventGCHeapMemoryPoolUsage event(UNTIMED);
+ event.set_name(pool->name());
+ event.set_used(usage.used());
+ event.set_committed(usage.committed());
+ event.set_max(usage.max_size());
+ event.set_starttime(timestamp());
+ event.set_endtime(timestamp());
+ event.commit();
+ }
+ }
+}
+
+
TRACE_REQUEST_FUNC(ClassLoadingStatistics) {
#if INCLUDE_MANAGEMENT
EventClassLoadingStatistics event;
diff --git a/src/jdk.jfr/share/conf/jfr/default.jfc b/src/jdk.jfr/share/conf/jfr/default.jfc
index e302da88433..acdb11ca61a 100644
--- a/src/jdk.jfr/share/conf/jfr/default.jfc
+++ b/src/jdk.jfr/share/conf/jfr/default.jfc
@@ -322,6 +322,16 @@
false
+
+ true
+ everyChunk
+
+
+
+ true
+ everyChunk
+
+
true
diff --git a/src/jdk.jfr/share/conf/jfr/profile.jfc b/src/jdk.jfr/share/conf/jfr/profile.jfc
index 841f20e4782..10e5518422c 100644
--- a/src/jdk.jfr/share/conf/jfr/profile.jfc
+++ b/src/jdk.jfr/share/conf/jfr/profile.jfc
@@ -322,6 +322,16 @@
false
+
+ true
+ everyChunk
+
+
+
+ true
+ everyChunk
+
+
true
diff --git a/test/jdk/jdk/jfr/event/gc/detailed/TestGCHeapMemoryPoolUsageEvent.java b/test/jdk/jdk/jfr/event/gc/detailed/TestGCHeapMemoryPoolUsageEvent.java
new file mode 100644
index 00000000000..33c1b04dbca
--- /dev/null
+++ b/test/jdk/jdk/jfr/event/gc/detailed/TestGCHeapMemoryPoolUsageEvent.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2023, 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
+ * 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 jdk.jfr.event.gc.detailed;
+
+import java.util.List;
+
+import jdk.jfr.Recording;
+import jdk.jfr.consumer.RecordedEvent;
+import jdk.test.lib.jfr.EventNames;
+import jdk.test.lib.jfr.Events;
+import static jdk.test.lib.Asserts.assertFalse;
+
+/**
+ * @test
+ * @key jfr
+ * @requires vm.hasJFR
+ * @library /test/lib /test/jdk
+ * @run main/othervm -XX:-ExplicitGCInvokesConcurrent jdk.jfr.event.gc.detailed.TestGCHeapMemoryPoolUsageEvent
+ */
+public class TestGCHeapMemoryPoolUsageEvent {
+ public static void main(String[] args) throws Exception {
+ try (Recording recording = new Recording()) {
+ recording.enable(EventNames.GCHeapMemoryPoolUsage);
+ recording.start();
+ System.gc();
+ recording.stop();
+
+ List events = Events.fromRecording(recording);
+ System.out.println(events);
+ assertFalse(events.isEmpty());
+
+ RecordedEvent event = events.get(0);
+ Events.assertField(event, "name").notNull();
+ Events.assertField(event, "used").atLeast(0L);
+ Events.assertField(event, "committed").atLeast(0L);
+ Events.assertField(event, "max").atLeast(-1L);
+ }
+ }
+}
+
+
diff --git a/test/jdk/jdk/jfr/event/gc/detailed/TestGCHeapMemoryUsageEvent.java b/test/jdk/jdk/jfr/event/gc/detailed/TestGCHeapMemoryUsageEvent.java
new file mode 100644
index 00000000000..61aa079ca23
--- /dev/null
+++ b/test/jdk/jdk/jfr/event/gc/detailed/TestGCHeapMemoryUsageEvent.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2023, 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
+ * 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 jdk.jfr.event.gc.detailed;
+
+import java.util.List;
+
+import jdk.jfr.Recording;
+import jdk.jfr.consumer.RecordedEvent;
+import jdk.test.lib.jfr.EventNames;
+import jdk.test.lib.jfr.Events;
+import static jdk.test.lib.Asserts.assertFalse;
+
+/**
+ * @test
+ * @key jfr
+ * @requires vm.hasJFR
+ * @library /test/lib /test/jdk
+ * @run main/othervm -XX:-ExplicitGCInvokesConcurrent jdk.jfr.event.gc.detailed.TestGCHeapMemoryUsageEvent
+ */
+public class TestGCHeapMemoryUsageEvent {
+ public static void main(String[] args) throws Exception {
+ try (Recording recording = new Recording()) {
+ recording.enable(EventNames.GCHeapMemoryUsage);
+ recording.start();
+ System.gc();
+ recording.stop();
+
+ List events = Events.fromRecording(recording);
+ System.out.println(events);
+ assertFalse(events.isEmpty());
+ RecordedEvent event = events.get(0);
+ Events.assertField(event, "used").above(0L);
+ Events.assertField(event, "committed").above(0L);
+ Events.assertField(event, "max").above(0L);
+ }
+ }
+}
+
diff --git a/test/lib/jdk/test/lib/jfr/EventNames.java b/test/lib/jdk/test/lib/jfr/EventNames.java
index de51d9b8547..9edeb3ff9a6 100644
--- a/test/lib/jdk/test/lib/jfr/EventNames.java
+++ b/test/lib/jdk/test/lib/jfr/EventNames.java
@@ -95,6 +95,8 @@ public class EventNames {
public static final String ReservedStackActivation = PREFIX + "ReservedStackActivation";
// GC
+ public static final String GCHeapMemoryUsage = PREFIX + "GCHeapMemoryUsage";
+ public static final String GCHeapMemoryPoolUsage = PREFIX + "GCHeapMemoryPoolUsage";
public static final String GCHeapSummary = PREFIX + "GCHeapSummary";
public static final String MetaspaceSummary = PREFIX + "MetaspaceSummary";
public static final String MetaspaceGCThreshold = PREFIX + "MetaspaceGCThreshold";