diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahGenerationalHeuristics.cpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahGenerationalHeuristics.cpp index 74c3f191e5f..5b6d82d97a4 100644 --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahGenerationalHeuristics.cpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahGenerationalHeuristics.cpp @@ -225,7 +225,7 @@ void ShenandoahGenerationalHeuristics::choose_collection_set(ShenandoahCollectio byte_size_in_proper_unit(old_evac_bytes), proper_unit_for_byte_size(old_evac_bytes), byte_size_in_proper_unit(total_evac_bytes), proper_unit_for_byte_size(total_evac_bytes)); - ShenandoahEvacInfo evacInfo; + ShenandoahEvacuationInformation evacInfo; evacInfo.set_collection_set_regions(collection_set->count()); evacInfo.set_collection_set_used_before(collection_set->used()); evacInfo.set_collection_set_used_after(collection_set->live()); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahEvacInfo.hpp b/src/hotspot/share/gc/shenandoah/shenandoahEvacInfo.hpp index ff106a70d65..5ca65763833 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahEvacInfo.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahEvacInfo.hpp @@ -27,8 +27,8 @@ #include "memory/allocation.hpp" -class ShenandoahEvacInfo : public StackObj { - // Values for ShenandoahEvacInfo jfr event, sizes stored as bytes +class ShenandoahEvacuationInformation : public StackObj { + // Values for ShenandoahEvacuationInformation jfr event, sizes stored as bytes size_t _collection_set_regions; size_t _collection_set_used_before; size_t _collection_set_used_after; @@ -44,7 +44,7 @@ class ShenandoahEvacInfo : public StackObj { size_t _immediate_size; public: - ShenandoahEvacInfo() : + ShenandoahEvacuationInformation() : _collection_set_regions(0), _collection_set_used_before(0), _collection_set_used_after(0), _collected_old(0), _collected_promoted(0), _collected_young(0), _regions_promoted_humongous(0), _regions_promoted_regular(0), _regular_promoted_garbage(0), _regular_promoted_free(0), diff --git a/src/hotspot/share/gc/shenandoah/shenandoahTrace.cpp b/src/hotspot/share/gc/shenandoah/shenandoahTrace.cpp index 828475d37f9..0e6453c9b35 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahTrace.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahTrace.cpp @@ -27,12 +27,12 @@ #include "gc/shenandoah/shenandoahTrace.hpp" #include "jfr/jfrEvents.hpp" -void ShenandoahTracer::report_evacuation_info(ShenandoahEvacInfo* info) { +void ShenandoahTracer::report_evacuation_info(ShenandoahEvacuationInformation* info) { send_evacuation_info_event(info); } -void ShenandoahTracer::send_evacuation_info_event(ShenandoahEvacInfo* info) { - EventShenandoahEvacInfo e; +void ShenandoahTracer::send_evacuation_info_event(ShenandoahEvacuationInformation* info) { + EventShenandoahEvacuationInformation e; if (e.should_commit()) { e.set_gcId(GCId::current()); e.set_cSetRegions(info->collection_set_regions()); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahTrace.hpp b/src/hotspot/share/gc/shenandoah/shenandoahTrace.hpp index f584ef207bb..a5351f4ef28 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahTrace.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahTrace.hpp @@ -28,15 +28,15 @@ #include "gc/shared/gcTrace.hpp" #include "memory/allocation.hpp" -class ShenandoahEvacInfo; +class ShenandoahEvacuationInformation; class ShenandoahTracer : public GCTracer, public CHeapObj<mtGC> { public: ShenandoahTracer() : GCTracer(Shenandoah) {} - void report_evacuation_info(ShenandoahEvacInfo* info); + void report_evacuation_info(ShenandoahEvacuationInformation* info); private: - void send_evacuation_info_event(ShenandoahEvacInfo* info); + void send_evacuation_info_event(ShenandoahEvacuationInformation* info); }; #endif diff --git a/src/hotspot/share/jfr/metadata/metadata.xml b/src/hotspot/share/jfr/metadata/metadata.xml index c5fccfc48d1..994c053a7b5 100644 --- a/src/hotspot/share/jfr/metadata/metadata.xml +++ b/src/hotspot/share/jfr/metadata/metadata.xml @@ -1202,7 +1202,7 @@ <Field type="string" name="state" label="State" /> </Type> - <Event name="ShenandoahEvacInfo" category="Java Virtual Machine, GC, Detailed" label="Shenandoah Evacuation Information" startTime="false"> + <Event name="ShenandoahEvacuationInformation" category="Java Virtual Machine, GC, Detailed" label="Shenandoah Evacuation Information" startTime="false"> <Field type="uint" name="gcId" label="GC Identifier" relation="GcId" /> <Field type="ulong" name="cSetRegions" label="Collection Set Regions" /> <Field type="ulong" contentType="bytes" name="cSetUsedBefore" label="Collection Set Before" description="Memory usage before GC in the collection set regions" /> diff --git a/src/jdk.jfr/share/conf/jfr/default.jfc b/src/jdk.jfr/share/conf/jfr/default.jfc index 4f0306562cd..57016a9bdd0 100644 --- a/src/jdk.jfr/share/conf/jfr/default.jfc +++ b/src/jdk.jfr/share/conf/jfr/default.jfc @@ -516,7 +516,7 @@ <setting name="enabled" control="gc-enabled-high">false</setting> </event> - <event name="jdk.ShenandoahEvacInfo"> + <event name="jdk.ShenandoahEvacuationInformation"> <setting name="enabled" control="gc-enabled-high">false</setting> </event> diff --git a/src/jdk.jfr/share/conf/jfr/profile.jfc b/src/jdk.jfr/share/conf/jfr/profile.jfc index e66f4e07321..1df3af7475f 100644 --- a/src/jdk.jfr/share/conf/jfr/profile.jfc +++ b/src/jdk.jfr/share/conf/jfr/profile.jfc @@ -516,7 +516,7 @@ <setting name="enabled" control="gc-enabled-high">false</setting> </event> - <event name="jdk.ShenandoahEvacInfo"> + <event name="jdk.ShenandoahEvacuationInformation"> <setting name="enabled" control="gc-enabled-high">false</setting> </event> diff --git a/test/jdk/jdk/jfr/event/gc/detailed/TestShenandoahEvacuationInformationEvent.java b/test/jdk/jdk/jfr/event/gc/detailed/TestShenandoahEvacuationInformationEvent.java new file mode 100644 index 00000000000..33310ab721a --- /dev/null +++ b/test/jdk/jdk/jfr/event/gc/detailed/TestShenandoahEvacuationInformationEvent.java @@ -0,0 +1,113 @@ +/* + * Copyright Amazon.com Inc. 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.time.Duration; +import java.util.List; +import java.util.Random; + +import jdk.jfr.Recording; +import jdk.jfr.consumer.RecordedEvent; +import jdk.test.lib.Asserts; +import jdk.test.lib.jfr.EventNames; +import jdk.test.lib.jfr.Events; +import jdk.test.lib.jfr.GCHelper; + +/** + * @test + * @bug 8221507 + * @requires vm.hasJFR & vm.gc.Shenandoah + * @key jfr + * @library /test/lib /test/jdk + * @run main/othervm -Xmx64m -XX:+UnlockExperimentalVMOptions -XX:ShenandoahRegionSize=1m -XX:+UseShenandoahGC -XX:ShenandoahGCMode=generational jdk.jfr.event.gc.detailed.TestShenandoahEvacuationInformationEvent + */ + +public class TestShenandoahEvacuationInformationEvent { + private final static String EVENT_NAME = EventNames.ShenandoahEvacuationInformation; + + public static void main(String[] args) throws Exception { + final long shenandoahHeapRegionSize = 1024 * 1024; + Recording recording = new Recording(); + recording.enable(EVENT_NAME).withThreshold(Duration.ofMillis(0)); + recording.start(); + allocate(); + recording.stop(); + + List<RecordedEvent> events = Events.fromRecording(recording); + Asserts.assertFalse(events.isEmpty(), "No events found"); + for (RecordedEvent event : events) { + if (!Events.isEventType(event, EVENT_NAME)) { + continue; + } + System.out.println("Event: " + event); + + long setRegions = Events.assertField(event, "cSetRegions").atLeast(0L).getValue(); + long setUsedAfter = Events.assertField(event, "cSetUsedAfter").atLeast(0L).getValue(); + long setUsedBefore = Events.assertField(event, "cSetUsedBefore").atLeast(setUsedAfter).getValue(); + long regionsFreed = Events.assertField(event, "regionsFreed").atLeast(0L).getValue(); + Events.assertField(event, "collectedOld").atLeast(0L).getValue(); + Events.assertField(event, "collectedYoung").atLeast(0L).getValue(); + + Asserts.assertGreaterThanOrEqual(setRegions, regionsFreed, "setRegions >= regionsFreed"); + Asserts.assertGreaterThanOrEqual(shenandoahHeapRegionSize * setRegions, setUsedAfter, "ShenandoahHeapRegionSize * setRegions >= setUsedAfter"); + Asserts.assertGreaterThanOrEqual(shenandoahHeapRegionSize * setRegions, setUsedBefore, "ShenandoahHeapRegionSize * setRegions >= setUsedBefore"); + + int gcId = Events.assertField(event, "gcId").getValue(); + } + } + + /** + * Allocate memory to trigger garbage collections. + * We want the allocated objects to have different life time, because we want both "young" and "old" objects. + * This is done by keeping the objects in an array and step the current index by a small random number in the loop. + * The loop will continue until we have allocated a fixed number of bytes. + */ + private static void allocate() { + DummyObject[] dummys = new DummyObject[6000]; + + Random r = new Random(0); + long bytesToAllocate = 256 * 1024 * 1024; + int currPos = 0; + while (bytesToAllocate > 0) { + int allocSize = 1000 + (r.nextInt(4000)); + bytesToAllocate -= allocSize; + dummys[currPos] = new DummyObject(allocSize); + + // Skip a few positions to get different duration on the objects. + currPos = (currPos + r.nextInt(20)) % dummys.length; + } + for (int c=0; c<dummys.length; c++) { + dummys[c] = null; + } + System.gc(); + } + + public static class DummyObject { + public byte[] payload; + DummyObject(int size) { + payload = new byte[size]; + } + } +} diff --git a/test/lib/jdk/test/lib/jfr/EventNames.java b/test/lib/jdk/test/lib/jfr/EventNames.java index 5ea58ab8464..77fe554c9ba 100644 --- a/test/lib/jdk/test/lib/jfr/EventNames.java +++ b/test/lib/jdk/test/lib/jfr/EventNames.java @@ -106,6 +106,7 @@ public class EventNames { public static final String G1HeapRegionTypeChange = PREFIX + "G1HeapRegionTypeChange"; public static final String ShenandoahHeapRegionInformation = PREFIX + "ShenandoahHeapRegionInformation"; public static final String ShenandoahHeapRegionStateChange = PREFIX + "ShenandoahHeapRegionStateChange"; + public static final String ShenandoahEvacuationInformation = PREFIX + "ShenandoahEvacuationInformation"; public static final String TenuringDistribution = PREFIX + "TenuringDistribution"; public static final String GarbageCollection = PREFIX + "GarbageCollection"; public static final String ParallelOldGarbageCollection = PREFIX + "ParallelOldGarbageCollection";