From 6ca8c8ce9afc61d1dd6928098d497a61651ae39d Mon Sep 17 00:00:00 2001 From: Jeffrey Bahr Date: Sat, 29 Mar 2025 17:02:42 -0700 Subject: [PATCH 1/3] [zgc] Add support for heap capacity summary Adds support for heap capacity summary. Adds fixes to ensure that temporary long[]'s and booleans are reset between phases to ensure no data is carried over between cycles. --- .../gctoolkit/event/zgc/FullZGCCycle.java | 4 +++ .../gctoolkit/event/zgc/ZGCCycle.java | 9 ++++++ .../event/zgc/ZGCHeapCapacitySummary.java | 25 +++++++++++++++ .../microsoft/gctoolkit/parser/ZGCParser.java | 31 +++++++++++++++++-- .../parser/GenerationalZGCParserTest.java | 12 +++++++ 5 files changed, 78 insertions(+), 3 deletions(-) create mode 100644 api/src/main/java/com/microsoft/gctoolkit/event/zgc/ZGCHeapCapacitySummary.java diff --git a/api/src/main/java/com/microsoft/gctoolkit/event/zgc/FullZGCCycle.java b/api/src/main/java/com/microsoft/gctoolkit/event/zgc/FullZGCCycle.java index 970648ed..543663a3 100644 --- a/api/src/main/java/com/microsoft/gctoolkit/event/zgc/FullZGCCycle.java +++ b/api/src/main/java/com/microsoft/gctoolkit/event/zgc/FullZGCCycle.java @@ -250,6 +250,10 @@ public double getMarkFollowDuration() { public ZGCMemoryPoolSummary getRelocateEnd() { return delegate.getRelocateEnd(); } + + public ZGCHeapCapacitySummary getHeapCapacitySummary() { + return delegate.getHeapCapacitySummary(); + } } // Concurrent Mark duration diff --git a/api/src/main/java/com/microsoft/gctoolkit/event/zgc/ZGCCycle.java b/api/src/main/java/com/microsoft/gctoolkit/event/zgc/ZGCCycle.java index cadc8410..d8c0d812 100644 --- a/api/src/main/java/com/microsoft/gctoolkit/event/zgc/ZGCCycle.java +++ b/api/src/main/java/com/microsoft/gctoolkit/event/zgc/ZGCCycle.java @@ -57,6 +57,7 @@ public class ZGCCycle { private ZGCReclaimSummary reclaimSummary; private ZGCMemorySummary memorySummary; private ZGCMetaspaceSummary metaspaceSummary; + private ZGCHeapCapacitySummary heapCapacitySummary; public ZGCReferenceSummary getSoftRefSummary() { return softRefSummary; @@ -493,4 +494,12 @@ public void setFinalRefSummary(ZGCReferenceSummary finalRefSummary) { public void setPhantomRefSummary(ZGCReferenceSummary phantomRefSummary) { this.phantomRefSummary = phantomRefSummary; } + + public void setHeapCapacitySummary(ZGCHeapCapacitySummary heapCapacitySummary) { + this.heapCapacitySummary = heapCapacitySummary; + } + + public ZGCHeapCapacitySummary getHeapCapacitySummary() { + return heapCapacitySummary; + } } diff --git a/api/src/main/java/com/microsoft/gctoolkit/event/zgc/ZGCHeapCapacitySummary.java b/api/src/main/java/com/microsoft/gctoolkit/event/zgc/ZGCHeapCapacitySummary.java new file mode 100644 index 00000000..bd3c7c18 --- /dev/null +++ b/api/src/main/java/com/microsoft/gctoolkit/event/zgc/ZGCHeapCapacitySummary.java @@ -0,0 +1,25 @@ +package com.microsoft.gctoolkit.event.zgc; + +public class ZGCHeapCapacitySummary { + private final long minCapacity; + private final long maxCapacity; + private final long softMaxCapacity; + + public ZGCHeapCapacitySummary(long minCapacity, long maxCapacity, long softMaxCapacity) { + this.minCapacity = minCapacity; + this.maxCapacity = maxCapacity; + this.softMaxCapacity = softMaxCapacity; + } + + public long getMinCapacity() { + return minCapacity; + } + + public long getMaxCapacity() { + return maxCapacity; + } + + public long getSoftMaxCapacity() { + return softMaxCapacity; + } +} diff --git a/parser/src/main/java/com/microsoft/gctoolkit/parser/ZGCParser.java b/parser/src/main/java/com/microsoft/gctoolkit/parser/ZGCParser.java index b0f03e18..e73316cd 100644 --- a/parser/src/main/java/com/microsoft/gctoolkit/parser/ZGCParser.java +++ b/parser/src/main/java/com/microsoft/gctoolkit/parser/ZGCParser.java @@ -13,6 +13,7 @@ import com.microsoft.gctoolkit.event.zgc.ZGCAllocatedSummary; import com.microsoft.gctoolkit.event.zgc.FullZGCCycle; import com.microsoft.gctoolkit.event.zgc.ZGCGarbageSummary; +import com.microsoft.gctoolkit.event.zgc.ZGCHeapCapacitySummary; import com.microsoft.gctoolkit.event.zgc.ZGCLiveSummary; import com.microsoft.gctoolkit.event.zgc.MajorZGCCycle; import com.microsoft.gctoolkit.event.zgc.OccupancySummary; @@ -35,6 +36,7 @@ import com.microsoft.gctoolkit.time.DateTimeStamp; import java.util.AbstractMap; +import java.util.Arrays; import java.util.Optional; import java.util.Set; import java.util.function.BiConsumer; @@ -65,6 +67,7 @@ public class ZGCParser extends UnifiedGCLogParser implements ZGCPatterns { private final long[] markEnd = new long[3]; private final long[] relocateStart = new long[3]; private final long[] relocateEnd = new long[3]; + private final long[] heapCapacity = new long[3]; private final MRUQueue> parseRules; private boolean oldGenHeapStats = false; @@ -349,7 +352,16 @@ private void referenceProcessingGen(GCLogTrace trace, String s) { } private void capacity(GCLogTrace trace, String s) { - //trace.notYetImplemented(); + ZGCForwardReference ref = getForwardRefForPhase(trace.getZCollectionPhase()); + + if ("Min Capacity".equals(trace.getGroup(2))){ + heapCapacity[0] = trace.toKBytes(3); + } else if ("Max Capacity".equals(trace.getGroup(2))) { + heapCapacity[1] = trace.toKBytes(3); + } else if ("Soft Max Capacity".equals(trace.getGroup(2))) { + heapCapacity[2] = trace.toKBytes(3); + ref.setHeapCapacitySummary(new ZGCHeapCapacitySummary(heapCapacity[0], heapCapacity[1], heapCapacity[2])); + } } private void captureAtIndex(GCLogTrace trace, int index) { @@ -487,8 +499,16 @@ private void memorySummary(GCLogTrace trace, String s) { break; } - // TODO: Consider using logging cycle duration instead of timestamps + // Clean up / reset temp variables + Arrays.fill(markStart, 0L); + Arrays.fill(markEnd, 0L); + Arrays.fill(relocateStart, 0L); + Arrays.fill(relocateEnd, 0L); + Arrays.fill(heapCapacity, 0L); + oldGenHeapStats = false; + youngGenHeapStats = false; + // TODO: Consider using logging cycle duration instead of timestamps publish(); } @@ -657,6 +677,7 @@ private static class ZGCForwardReference implements ZForwardReference { // Memory + private ZGCHeapCapacitySummary heapCapacitySummary; private ZGCMemoryPoolSummary markStart; private ZGCMemoryPoolSummary markEnd; private ZGCMemoryPoolSummary relocatedStart; @@ -758,6 +779,7 @@ public ZGCCycle getZGCCycle(DateTimeStamp endTime) { cycle.setPhantomRefSummary(phantomRefSummary); //Memory + cycle.setHeapCapacitySummary(heapCapacitySummary); cycle.setMarkStart(markStart); cycle.setMarkEnd(markEnd); cycle.setRelocateStart(relocatedStart); @@ -774,7 +796,6 @@ public ZGCCycle getZGCCycle(DateTimeStamp endTime) { return cycle; } - public void setPauseMarkStart(DateTimeStamp pauseMarkStart) { this.pauseMarkStart = pauseMarkStart; } @@ -1005,6 +1026,10 @@ public void setFinalRefSummary(ZGCReferenceSummary finalRefSummary) { public void setPhantomRefSummary(ZGCReferenceSummary phantomRefSummary) { this.phantomRefSummary = phantomRefSummary; } + + public void setHeapCapacitySummary(ZGCHeapCapacitySummary heapCapacitySummary) { + this.heapCapacitySummary = heapCapacitySummary; + } } @Override diff --git a/parser/src/test/java/com/microsoft/gctoolkit/parser/GenerationalZGCParserTest.java b/parser/src/test/java/com/microsoft/gctoolkit/parser/GenerationalZGCParserTest.java index 243dd03f..f7d89167 100644 --- a/parser/src/test/java/com/microsoft/gctoolkit/parser/GenerationalZGCParserTest.java +++ b/parser/src/test/java/com/microsoft/gctoolkit/parser/GenerationalZGCParserTest.java @@ -10,6 +10,7 @@ import com.microsoft.gctoolkit.event.zgc.ZGCCompactedSummary; import com.microsoft.gctoolkit.event.zgc.ZGCCycle; import com.microsoft.gctoolkit.event.zgc.ZGCGarbageSummary; +import com.microsoft.gctoolkit.event.zgc.ZGCHeapCapacitySummary; import com.microsoft.gctoolkit.event.zgc.ZGCLiveSummary; import com.microsoft.gctoolkit.event.zgc.ZGCMemoryPoolSummary; import com.microsoft.gctoolkit.event.zgc.ZGCMemorySummary; @@ -163,6 +164,8 @@ public void testZgcMajorCycle() { assertEquals(toInt(13.129d, 1000), toInt(young.getConcurrentRelocateDuration(), 1000)); //Memory + assertTrue(checkZGCHeapSummary(young.getHeapCapacitySummary(), 36864, 36864, 36864)); + assertTrue(checkZGCMemoryPoolSummary(young.getMarkStart(), 36864, 36568, 296)); assertTrue(checkZGCMemoryPoolSummary(young.getMarkEnd(), 36864, 36556, 308)); assertTrue(checkZGCMemoryPoolSummary(young.getRelocateStart(),36864, 36624, 240)); @@ -223,6 +226,8 @@ public void testZgcMajorCycle() { assertTrue(checkReferenceSummary(old.getPhantomRefSummary(), 497, 0, 0)); //Memory + assertTrue(checkZGCHeapSummary(old.getHeapCapacitySummary(), 36864, 36864, 36864)); + assertTrue(checkZGCMemoryPoolSummary(old.getMarkStart(), 36864, 36568, 296)); assertTrue(checkZGCMemoryPoolSummary(old.getMarkEnd(), 36864, 36788, 76 )); assertTrue(checkZGCMemoryPoolSummary(old.getRelocateStart(),36864, 36784, 80)); @@ -343,6 +348,8 @@ public void testZgcMinorCycle() { assertEquals(toInt(198.752d, 1000), toInt(young.getConcurrentRelocateDuration(), 1000)); //Memory + assertTrue(checkZGCHeapSummary(young.getHeapCapacitySummary(), 36864, 36864, 36864)); + assertTrue(checkZGCMemoryPoolSummary(young.getMarkStart(), 36864, 22144, 14720)); assertTrue(checkZGCMemoryPoolSummary(young.getMarkEnd(), 36864, 21376, 15488)); assertTrue(checkZGCMemoryPoolSummary(young.getRelocateStart(),36864, 23912, 12952)); @@ -393,6 +400,11 @@ private boolean checkZGCMetaSpaceSummary(ZGCMetaspaceSummary summary, long usedM return summary.getUsed() ==(usedMb * 1024) && summary.getCommitted() == (committedMb * 1024) && summary.getReserved() == (reservedMb * 1024); } + private boolean checkZGCHeapSummary(ZGCHeapCapacitySummary summary, long minCapacityMb, long maxCapacityMb , long softMaxCapacityMb) { + return summary.getMinCapacity() == (minCapacityMb * 1024) && summary.getMaxCapacity() == (maxCapacityMb * 1024) && summary.getSoftMaxCapacity() == (softMaxCapacityMb * 1024); + } + + private boolean checkZGCMemoryPoolSummary(ZGCMemoryPoolSummary summary, long capacityMb, long freeMb , long usedMb) { return summary.getCapacity() == (capacityMb * 1024) && summary.getFree() == (freeMb * 1024) && summary.getUsed() == (usedMb * 1024); } From cbd5bf2d6771964ad24d478d3e27d4c0b268b324 Mon Sep 17 00:00:00 2001 From: Jeffrey Bahr Date: Sat, 29 Mar 2025 17:27:52 -0700 Subject: [PATCH 2/3] [zgc] Add support for nMethod tracking Adds support for nMethod tracking in generational ZGC young and old generations. --- .../gctoolkit/event/zgc/FullZGCCycle.java | 4 ++++ .../gctoolkit/event/zgc/ZGCCycle.java | 9 +++++++++ .../event/zgc/ZGCNMethodSummary.java | 19 +++++++++++++++++++ .../microsoft/gctoolkit/parser/ZGCParser.java | 14 +++++++++++++- .../parser/GenerationalZGCParserTest.java | 12 ++++++++++++ 5 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 api/src/main/java/com/microsoft/gctoolkit/event/zgc/ZGCNMethodSummary.java diff --git a/api/src/main/java/com/microsoft/gctoolkit/event/zgc/FullZGCCycle.java b/api/src/main/java/com/microsoft/gctoolkit/event/zgc/FullZGCCycle.java index 543663a3..7a745324 100644 --- a/api/src/main/java/com/microsoft/gctoolkit/event/zgc/FullZGCCycle.java +++ b/api/src/main/java/com/microsoft/gctoolkit/event/zgc/FullZGCCycle.java @@ -254,6 +254,10 @@ public ZGCMemoryPoolSummary getRelocateEnd() { public ZGCHeapCapacitySummary getHeapCapacitySummary() { return delegate.getHeapCapacitySummary(); } + + public ZGCNMethodSummary getNMethodSummary() { + return delegate.getNMethodSummary(); + } } // Concurrent Mark duration diff --git a/api/src/main/java/com/microsoft/gctoolkit/event/zgc/ZGCCycle.java b/api/src/main/java/com/microsoft/gctoolkit/event/zgc/ZGCCycle.java index d8c0d812..c1f246c5 100644 --- a/api/src/main/java/com/microsoft/gctoolkit/event/zgc/ZGCCycle.java +++ b/api/src/main/java/com/microsoft/gctoolkit/event/zgc/ZGCCycle.java @@ -58,6 +58,7 @@ public class ZGCCycle { private ZGCMemorySummary memorySummary; private ZGCMetaspaceSummary metaspaceSummary; private ZGCHeapCapacitySummary heapCapacitySummary; + private ZGCNMethodSummary nMethodSummary; public ZGCReferenceSummary getSoftRefSummary() { return softRefSummary; @@ -502,4 +503,12 @@ public void setHeapCapacitySummary(ZGCHeapCapacitySummary heapCapacitySummary) { public ZGCHeapCapacitySummary getHeapCapacitySummary() { return heapCapacitySummary; } + + public void setNMethodSummary(ZGCNMethodSummary nMethodSummary) { + this.nMethodSummary = nMethodSummary; + } + + public ZGCNMethodSummary getNMethodSummary() { + return nMethodSummary; + } } diff --git a/api/src/main/java/com/microsoft/gctoolkit/event/zgc/ZGCNMethodSummary.java b/api/src/main/java/com/microsoft/gctoolkit/event/zgc/ZGCNMethodSummary.java new file mode 100644 index 00000000..1baf47f9 --- /dev/null +++ b/api/src/main/java/com/microsoft/gctoolkit/event/zgc/ZGCNMethodSummary.java @@ -0,0 +1,19 @@ +package com.microsoft.gctoolkit.event.zgc; + +public class ZGCNMethodSummary { + private final long registered; + private final long unregistered; + + public ZGCNMethodSummary(long registered, long unregistered) { + this.registered = registered; + this.unregistered = unregistered; + } + + public long getUnregistered() { + return unregistered; + } + + public long getRegistered() { + return registered; + } +} diff --git a/parser/src/main/java/com/microsoft/gctoolkit/parser/ZGCParser.java b/parser/src/main/java/com/microsoft/gctoolkit/parser/ZGCParser.java index e73316cd..30fb4239 100644 --- a/parser/src/main/java/com/microsoft/gctoolkit/parser/ZGCParser.java +++ b/parser/src/main/java/com/microsoft/gctoolkit/parser/ZGCParser.java @@ -18,6 +18,7 @@ import com.microsoft.gctoolkit.event.zgc.MajorZGCCycle; import com.microsoft.gctoolkit.event.zgc.OccupancySummary; import com.microsoft.gctoolkit.event.zgc.ZGCCompactedSummary; +import com.microsoft.gctoolkit.event.zgc.ZGCNMethodSummary; import com.microsoft.gctoolkit.event.zgc.ZGCPhase; import com.microsoft.gctoolkit.event.zgc.ZGCPromotedSummary; import com.microsoft.gctoolkit.event.zgc.ZGCReclaimSummary; @@ -319,7 +320,12 @@ private void relocationSummary(GCLogTrace trace, String s) { } private void nMethods(GCLogTrace trace, String s) { - //trace.notYetImplemented(); + ZGCForwardReference ref = getForwardRefForPhase(trace.getZCollectionPhase()); + + ZGCNMethodSummary summary = new ZGCNMethodSummary( + trace.getLongGroup(2), + trace.getLongGroup(3)); + ref.setNMethodSummary(summary); } private void metaspace(GCLogTrace trace, String s) { @@ -713,6 +719,7 @@ private static class ZGCForwardReference implements ZForwardReference { private ZGCReferenceSummary weakRefSummary; private ZGCReferenceSummary finalRefSummary; private ZGCReferenceSummary phantomRefSummary; + private ZGCNMethodSummary nMethodSummary; public ZGCForwardReference(DateTimeStamp dateTimeStamp, long gcId, GCCause cause, ZGCCollectionType type, ZGCPhase phase) { this.startTimeStamp = dateTimeStamp; @@ -793,6 +800,7 @@ public ZGCCycle getZGCCycle(DateTimeStamp endTime) { cycle.setLoadAverages(load); cycle.setMMU(mmu); cycle.setMarkSummary(markSummary); + cycle.setNMethodSummary(nMethodSummary); return cycle; } @@ -1030,6 +1038,10 @@ public void setPhantomRefSummary(ZGCReferenceSummary phantomRefSummary) { public void setHeapCapacitySummary(ZGCHeapCapacitySummary heapCapacitySummary) { this.heapCapacitySummary = heapCapacitySummary; } + + public void setNMethodSummary(ZGCNMethodSummary nMethodSummary) { + this.nMethodSummary = nMethodSummary; + } } @Override diff --git a/parser/src/test/java/com/microsoft/gctoolkit/parser/GenerationalZGCParserTest.java b/parser/src/test/java/com/microsoft/gctoolkit/parser/GenerationalZGCParserTest.java index f7d89167..63d914b6 100644 --- a/parser/src/test/java/com/microsoft/gctoolkit/parser/GenerationalZGCParserTest.java +++ b/parser/src/test/java/com/microsoft/gctoolkit/parser/GenerationalZGCParserTest.java @@ -60,6 +60,7 @@ public void testZgcMajorCycle() { "[2025-02-11T13:06:19.551-0800][info][gc,mmu ] GC(1) Y: MMU: 2ms/98.9%, 5ms/99.5%, 10ms/99.8%, 20ms/99.8%, 50ms/99.9%, 100ms/99.9%", "[2025-02-11T13:06:19.551-0800][info][gc,marking ] GC(1) Y: Mark: 1 stripe(s), 2 proactive flush(es), 1 terminate flush(es), 0 completion(s), 0 continuation(s) ", "[2025-02-11T13:06:19.551-0800][info][gc,marking ] GC(1) Y: Mark Stack Usage: 32M", + "[2025-02-11T13:06:19.551-0800][info][gc,nmethod ] GC(1) Y: NMethods: 2335 registered, 0 unregistered", "[2025-02-11T13:06:19.551-0800][info][gc,metaspace] GC(1) Y: Metaspace: 36M used, 37M committed, 1088M reserved", "[2025-02-11T13:06:19.551-0800][info][gc,reloc ] GC(1) Y: Candidates Selected In-Place Size Empty Relocated ", "[2025-02-11T13:06:19.551-0800][info][gc,reloc ] GC(1) Y: Small Pages: 112 85 0 224M 36M 6M ", @@ -102,6 +103,7 @@ public void testZgcMajorCycle() { "[2025-02-11T13:06:19.580-0800][info][gc,mmu ] GC(1) O: MMU: 2ms/98.9%, 5ms/99.5%, 10ms/99.8%, 20ms/99.8%, 50ms/99.9%, 100ms/99.9%", "[2025-02-11T13:06:19.580-0800][info][gc,marking ] GC(1) O: Mark: 1 stripe(s), 1 proactive flush(es), 1 terminate flush(es), 0 completion(s), 0 continuation(s) ", "[2025-02-11T13:06:19.580-0800][info][gc,marking ] GC(1) O: Mark Stack Usage: 0M", + "[2025-02-11T13:06:19.580-0800][info][gc,nmethod ] GC(1) O: NMethods: 5978 registered, 1490 unregistered", "[2025-02-11T13:06:19.580-0800][info][gc,metaspace] GC(1) O: Metaspace: 36M used, 37M committed, 1088M reserved", "[2025-02-11T13:06:19.580-0800][info][gc,ref ] GC(1) O: Encountered Discovered Enqueued ", "[2025-02-11T13:06:19.580-0800][info][gc,ref ] GC(1) O: Soft References: 4193 0 0 ", @@ -182,6 +184,9 @@ public void testZgcMajorCycle() { assertTrue(checkPromotedSummary(young.getPromotedSummary(), 0, 0)); assertTrue(checkCompactedSummary(young.getCompactedSummary(), 10)); + assertEquals(2335, young.getNMethodSummary().getRegistered()); + assertEquals(0, young.getNMethodSummary().getUnregistered()); + assertEquals(7.61, young.getLoadAverageAt(1)); assertEquals(12.83, young.getLoadAverageAt(5)); assertEquals(13.76, young.getLoadAverageAt(15)); @@ -244,6 +249,9 @@ public void testZgcMajorCycle() { assertNull(old.getPromotedSummary()); assertTrue(checkCompactedSummary(old.getCompactedSummary(), 0)); + assertEquals(5978, old.getNMethodSummary().getRegistered()); + assertEquals(1490, old.getNMethodSummary().getUnregistered()); + assertEquals(7.61, old.getLoadAverageAt(1)); assertEquals(12.83, old.getLoadAverageAt(5)); assertEquals(13.76, old.getLoadAverageAt(15)); @@ -280,6 +288,7 @@ public void testZgcMinorCycle() { "[2025-02-11T13:07:13.255-0800][info][gc,mmu ] GC(7) y: MMU: 2ms/97.7%, 5ms/99.1%, 10ms/99.5%, 20ms/99.8%, 50ms/99.9%, 100ms/99.9%", "[2025-02-11T13:07:13.255-0800][info][gc,marking ] GC(7) y: Mark: 1 stripe(s), 2 proactive flush(es), 1 terminate flush(es), 0 completion(s), 0 continuation(s) ", "[2025-02-11T13:07:13.255-0800][info][gc,marking ] GC(7) y: Mark Stack Usage: 32M", + "[2025-02-11T13:07:13.255-0800][info][gc,nmethod ] GC(7) y: NMethods: 2335 registered, 0 unregistered", "[2025-02-11T13:07:13.255-0800][info][gc,metaspace] GC(7) y: Metaspace: 100M used, 101M committed, 1152M reserved", "[2025-02-11T13:07:13.255-0800][info][gc,reloc ] GC(7) y: Candidates Selected In-Place Size Empty Relocated ", "[2025-02-11T13:07:13.255-0800][info][gc,reloc ] GC(7) y: Small Pages: 7066 5720 0 14132M 2554M 74M ", @@ -366,6 +375,9 @@ public void testZgcMinorCycle() { assertTrue(checkPromotedSummary(young.getPromotedSummary(), 0, 0)); assertTrue(checkCompactedSummary(young.getCompactedSummary(), 104)); + assertEquals(2335, young.getNMethodSummary().getRegistered()); + assertEquals(0, young.getNMethodSummary().getUnregistered()); + assertEquals(17.42, young.getLoadAverageAt(1)); assertEquals(14.37, young.getLoadAverageAt(5)); assertEquals(14.21, young.getLoadAverageAt(15)); From 7e97a43e414348b7806fe272d666b15f18ba4c48 Mon Sep 17 00:00:00 2001 From: Jeffrey Bahr Date: Sat, 29 Mar 2025 21:43:10 -0700 Subject: [PATCH 3/3] [zgc] Add support for relocation summary This commit adds support for all the information for gc,reloc stats. This includes Small, Medium and Large page stats, bytes forward and the age table for all the pages, including Eden and Survivor generations. The Small, Medium and Large table stats are directly accessible on the ZGC cycle, where the page age summaries for Eden and all Survivor generations are included as a variable sized list. As far as I can tell this list can be as long at 14. --- .../gctoolkit/event/zgc/FullZGCCycle.java | 22 +++++ .../gctoolkit/event/zgc/ZGCCycle.java | 48 +++++++++++ .../event/zgc/ZGCPageAgeSummary.java | 84 ++++++++++++++++++ .../gctoolkit/event/zgc/ZGCPageSummary.java | 43 ++++++++++ .../microsoft/gctoolkit/parser/ZGCParser.java | 85 +++++++++++++++++++ .../gctoolkit/parser/unified/ZGCPatterns.java | 16 ++++ .../parser/GenerationalZGCParserTest.java | 53 +++++++++++- 7 files changed, 349 insertions(+), 2 deletions(-) create mode 100644 api/src/main/java/com/microsoft/gctoolkit/event/zgc/ZGCPageAgeSummary.java create mode 100644 api/src/main/java/com/microsoft/gctoolkit/event/zgc/ZGCPageSummary.java diff --git a/api/src/main/java/com/microsoft/gctoolkit/event/zgc/FullZGCCycle.java b/api/src/main/java/com/microsoft/gctoolkit/event/zgc/FullZGCCycle.java index 7a745324..a3dc0345 100644 --- a/api/src/main/java/com/microsoft/gctoolkit/event/zgc/FullZGCCycle.java +++ b/api/src/main/java/com/microsoft/gctoolkit/event/zgc/FullZGCCycle.java @@ -7,6 +7,8 @@ import com.microsoft.gctoolkit.event.GarbageCollectionTypes; import com.microsoft.gctoolkit.time.DateTimeStamp; +import java.util.List; + public class FullZGCCycle extends GCEvent { private ZGCCycle delegate; @@ -258,6 +260,26 @@ public ZGCHeapCapacitySummary getHeapCapacitySummary() { public ZGCNMethodSummary getNMethodSummary() { return delegate.getNMethodSummary(); } + + public ZGCPageSummary getSmallPageSummary() { + return delegate.getSmallPageSummary(); + } + + public ZGCPageSummary getMediumPageSummary() { + return delegate.getMediumPageSummary(); + } + + public ZGCPageSummary getLargePageSummary() { + return delegate.getLargePageSummary(); + } + + public long getForwardingUsage() { + return delegate.getForwardingUsage(); + } + + public List getAgeTableSummary() { + return delegate.getAgeTableSummary(); + } } // Concurrent Mark duration diff --git a/api/src/main/java/com/microsoft/gctoolkit/event/zgc/ZGCCycle.java b/api/src/main/java/com/microsoft/gctoolkit/event/zgc/ZGCCycle.java index c1f246c5..d06173f8 100644 --- a/api/src/main/java/com/microsoft/gctoolkit/event/zgc/ZGCCycle.java +++ b/api/src/main/java/com/microsoft/gctoolkit/event/zgc/ZGCCycle.java @@ -2,6 +2,8 @@ import com.microsoft.gctoolkit.time.DateTimeStamp; +import java.util.List; + public class ZGCCycle { private DateTimeStamp markRootsStart; private double markRootsDuration; @@ -60,6 +62,12 @@ public class ZGCCycle { private ZGCHeapCapacitySummary heapCapacitySummary; private ZGCNMethodSummary nMethodSummary; + private ZGCPageSummary smallPageSummary; + private ZGCPageSummary mediumPageSummary; + private ZGCPageSummary largePageSummary; + private long forwardingUsage; + private List ageTableSummary; + public ZGCReferenceSummary getSoftRefSummary() { return softRefSummary; } @@ -511,4 +519,44 @@ public void setNMethodSummary(ZGCNMethodSummary nMethodSummary) { public ZGCNMethodSummary getNMethodSummary() { return nMethodSummary; } + + public void setSmallPageSummary(ZGCPageSummary smallPageSummary) { + this.smallPageSummary = smallPageSummary; + } + + public void setMediumPageSummary(ZGCPageSummary mediumPageSummary) { + this.mediumPageSummary = mediumPageSummary; + } + + public void setLargePageSummary(ZGCPageSummary largePageSummary) { + this.largePageSummary = largePageSummary; + } + + public ZGCPageSummary getSmallPageSummary() { + return smallPageSummary; + } + + public ZGCPageSummary getMediumPageSummary() { + return mediumPageSummary; + } + + public ZGCPageSummary getLargePageSummary() { + return largePageSummary; + } + + public void setForwardingUsage(long forwardingUsage) { + this.forwardingUsage = forwardingUsage; + } + + public long getForwardingUsage() { + return forwardingUsage; + } + + public void setAgeTableSummary(List ageTableSummary) { + this.ageTableSummary = ageTableSummary; + } + + public List getAgeTableSummary() { + return ageTableSummary; + } } diff --git a/api/src/main/java/com/microsoft/gctoolkit/event/zgc/ZGCPageAgeSummary.java b/api/src/main/java/com/microsoft/gctoolkit/event/zgc/ZGCPageAgeSummary.java new file mode 100644 index 00000000..76e9c3e4 --- /dev/null +++ b/api/src/main/java/com/microsoft/gctoolkit/event/zgc/ZGCPageAgeSummary.java @@ -0,0 +1,84 @@ +package com.microsoft.gctoolkit.event.zgc; + +public class ZGCPageAgeSummary { + private final String name; + private final long live; + private final int livePct; + private final long garbage; + private final int garbagePct; + private final long smallPageCandidates; + private final long smallPageSelected; + private final long mediumPageCandidates; + private final long mediumPageSelected; + private final long largePageCandidates; + private final long largePageSelected; + + public ZGCPageAgeSummary( + String name, + long live, + int livePct, + long garbage, + int garbagePct, + long smallPageCandidates, + long smallPageSelected, + long mediumPageCandidates, + long mediumPageSelected, + long largePageCandidates, + long largePageSelected) { + this.name = name; + this.live = live; + this.livePct = livePct; + this.garbage = garbage; + this.garbagePct = garbagePct; + this.smallPageCandidates = smallPageCandidates; + this.smallPageSelected = smallPageSelected; + this.mediumPageCandidates = mediumPageCandidates; + this.mediumPageSelected = mediumPageSelected; + this.largePageCandidates = largePageCandidates; + this.largePageSelected = largePageSelected; + } + + public long getGarbage() { + return garbage; + } + + public int getGarbagePct() { + return garbagePct; + } + + public long getLargePageCandidates() { + return largePageCandidates; + } + + public long getLargePageSelected() { + return largePageSelected; + } + + public long getLive() { + return live; + } + + public int getLivePct() { + return livePct; + } + + public long getMediumPageCandidates() { + return mediumPageCandidates; + } + + public long getMediumPageSelected() { + return mediumPageSelected; + } + + public String getName() { + return name; + } + + public long getSmallPageCandidates() { + return smallPageCandidates; + } + + public long getSmallPageSelected() { + return smallPageSelected; + } +} diff --git a/api/src/main/java/com/microsoft/gctoolkit/event/zgc/ZGCPageSummary.java b/api/src/main/java/com/microsoft/gctoolkit/event/zgc/ZGCPageSummary.java new file mode 100644 index 00000000..433a7290 --- /dev/null +++ b/api/src/main/java/com/microsoft/gctoolkit/event/zgc/ZGCPageSummary.java @@ -0,0 +1,43 @@ +package com.microsoft.gctoolkit.event.zgc; + +public class ZGCPageSummary { + private final long candidates; + private final long selected; + private final long inPlace; + private final long size; + private final long empty; + private final long relocated; + + public ZGCPageSummary(long candidates, long selected, long inPlace, long size, long empty, long relocated) { + this.candidates = candidates; + this.selected = selected; + this.inPlace = inPlace; + this.size = size; + this.empty = empty; + this.relocated = relocated; + } + + public long getCandidates() { + return candidates; + } + + public long getEmpty() { + return empty; + } + + public long getInPlace() { + return inPlace; + } + + public long getRelocated() { + return relocated; + } + + public long getSelected() { + return selected; + } + + public long getSize() { + return size; + } +} diff --git a/parser/src/main/java/com/microsoft/gctoolkit/parser/ZGCParser.java b/parser/src/main/java/com/microsoft/gctoolkit/parser/ZGCParser.java index 30fb4239..cad0aaf9 100644 --- a/parser/src/main/java/com/microsoft/gctoolkit/parser/ZGCParser.java +++ b/parser/src/main/java/com/microsoft/gctoolkit/parser/ZGCParser.java @@ -9,6 +9,7 @@ import com.microsoft.gctoolkit.event.GarbageCollectionTypes; import com.microsoft.gctoolkit.event.jvm.JVMEvent; import com.microsoft.gctoolkit.event.jvm.JVMTermination; +import com.microsoft.gctoolkit.event.zgc.ZGCPageAgeSummary; import com.microsoft.gctoolkit.event.zgc.MinorZGCCycle; import com.microsoft.gctoolkit.event.zgc.ZGCAllocatedSummary; import com.microsoft.gctoolkit.event.zgc.FullZGCCycle; @@ -19,6 +20,7 @@ import com.microsoft.gctoolkit.event.zgc.OccupancySummary; import com.microsoft.gctoolkit.event.zgc.ZGCCompactedSummary; import com.microsoft.gctoolkit.event.zgc.ZGCNMethodSummary; +import com.microsoft.gctoolkit.event.zgc.ZGCPageSummary; import com.microsoft.gctoolkit.event.zgc.ZGCPhase; import com.microsoft.gctoolkit.event.zgc.ZGCPromotedSummary; import com.microsoft.gctoolkit.event.zgc.ZGCReclaimSummary; @@ -37,7 +39,9 @@ import com.microsoft.gctoolkit.time.DateTimeStamp; import java.util.AbstractMap; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; import java.util.Optional; import java.util.Set; import java.util.function.BiConsumer; @@ -99,6 +103,9 @@ public class ZGCParser extends UnifiedGCLogParser implements ZGCPatterns { parseRules.put(LOAD_GEN, this::loadGen); parseRules.put(REFERENCE_PROCESSING_GEN, this::referenceProcessingGen); parseRules.put(END_OF_PHASE_SUMMARY_GEN, this::endOfPhaseMemorySummary); + parseRules.put(PAGES_GEN, this::pageSummary); + parseRules.put(FORWARDING_USAGE_GEN, this::forwardingUsage); + parseRules.put(AGE_TABLE_GEN, this::ageTable); // Phase change rules parseRules.put(MARK_OLD_GEN_HEAP_STATS, this::markOldGenHeapStats); @@ -271,6 +278,50 @@ private void concurrentPhase(GCLogTrace trace, String s) { trace.notYetImplemented(); } + + private void pageSummary(GCLogTrace trace, String s) { + ZGCForwardReference ref = getForwardRefForPhase(trace.getZCollectionPhase()); + + ZGCPageSummary summary = new ZGCPageSummary( + trace.getLongGroup(3), + trace.getLongGroup(4), + trace.getLongGroup(5), + trace.toKBytes(6), + trace.toKBytes(8), + trace.toKBytes(10)); + if ("Small".equals(trace.getGroup(2))){ + ref.setSmallPageSummary(summary); + } else if ("Medium".equals(trace.getGroup(2))) { + ref.setMediumPageSummary(summary); + } else if ("Large".equals(trace.getGroup(2))) { + ref.setLargePageSummary(summary); + } + } + + private void forwardingUsage(GCLogTrace trace, String s) { + ZGCForwardReference ref = getForwardRefForPhase(trace.getZCollectionPhase()); + + ref.setForwardingUsage(trace.toKBytes(2)); + } + + private void ageTable(GCLogTrace trace, String s) { + ZGCForwardReference ref = getForwardRefForPhase(trace.getZCollectionPhase()); + + ZGCPageAgeSummary summary = new ZGCPageAgeSummary( + trace.getGroup(2), + trace.toKBytes(3), + trace.getIntegerGroup(5), + trace.toKBytes(6), + trace.getIntegerGroup(8), + trace.getLongGroup(9), + trace.getLongGroup(10), + trace.getLongGroup(11), + trace.getLongGroup(12), + trace.getLongGroup(13), + trace.getLongGroup(14)); + ref.addPageAgeSummary(summary); + } + private void load(GCLogTrace trace, String s) { ZGCForwardReference ref = getForwardRefForPhase(trace.getZCollectionPhase()); @@ -720,6 +771,11 @@ private static class ZGCForwardReference implements ZForwardReference { private ZGCReferenceSummary finalRefSummary; private ZGCReferenceSummary phantomRefSummary; private ZGCNMethodSummary nMethodSummary; + private ZGCPageSummary smallPageSummary; + private ZGCPageSummary mediumPageSummary; + private ZGCPageSummary largePageSummary; + private long forwardingUsage; + private List ageTableSummary; public ZGCForwardReference(DateTimeStamp dateTimeStamp, long gcId, GCCause cause, ZGCCollectionType type, ZGCPhase phase) { this.startTimeStamp = dateTimeStamp; @@ -801,6 +857,11 @@ public ZGCCycle getZGCCycle(DateTimeStamp endTime) { cycle.setMMU(mmu); cycle.setMarkSummary(markSummary); cycle.setNMethodSummary(nMethodSummary); + cycle.setSmallPageSummary(smallPageSummary); + cycle.setMediumPageSummary(mediumPageSummary); + cycle.setLargePageSummary(largePageSummary); + cycle.setForwardingUsage(forwardingUsage); + cycle.setAgeTableSummary(ageTableSummary); return cycle; } @@ -1042,6 +1103,30 @@ public void setHeapCapacitySummary(ZGCHeapCapacitySummary heapCapacitySummary) { public void setNMethodSummary(ZGCNMethodSummary nMethodSummary) { this.nMethodSummary = nMethodSummary; } + + public void setSmallPageSummary(ZGCPageSummary smallPageSummary) { + this.smallPageSummary = smallPageSummary; + } + + public void setMediumPageSummary(ZGCPageSummary mediumPageSummary) { + this.mediumPageSummary = mediumPageSummary; + } + + public void setLargePageSummary(ZGCPageSummary largePageSummary) { + this.largePageSummary = largePageSummary; + } + + public void setForwardingUsage(long forwardingUsage) { + this.forwardingUsage = forwardingUsage; + } + + public void addPageAgeSummary(ZGCPageAgeSummary summary) { + if (this.ageTableSummary == null) { + this.ageTableSummary = new ArrayList<>(); + } + + ageTableSummary.add(summary); + } } @Override diff --git a/parser/src/main/java/com/microsoft/gctoolkit/parser/unified/ZGCPatterns.java b/parser/src/main/java/com/microsoft/gctoolkit/parser/unified/ZGCPatterns.java index c5fd0e70..0688540e 100644 --- a/parser/src/main/java/com/microsoft/gctoolkit/parser/unified/ZGCPatterns.java +++ b/parser/src/main/java/com/microsoft/gctoolkit/parser/unified/ZGCPatterns.java @@ -47,6 +47,22 @@ public interface ZGCPatterns extends UnifiedPatterns { //[3.596s][info ][gc,reloc ] GC(3) Relocation: Successful, 6M relocated GCParseRule RELOCATION_SUMMARY = new GCParseRule("Relocation Summary",OPT_GEN + "Relocation: Successful, (\\d+)M relocated"); + //[2025-03-07T17:46:45.563-0800][info][gc,reloc ] GC(380) Y: Candidates Selected In-Place Size Empty Relocated + //[2025-03-07T17:46:45.563-0800][info][gc,reloc ] GC(380) Y: Small Pages: 53993 26715 0 107986M 53924M 180M + //[2025-03-07T17:46:45.563-0800][info][gc,reloc ] GC(380) Y: Medium Pages: 2 0 0 64M 32M 0M + //[2025-03-07T17:46:45.563-0800][info][gc,reloc ] GC(380) Y: Large Pages: 0 0 0 0M 0M 0M + GCParseRule PAGES_GEN = new GCParseRule("Page Summary",OPT_GEN + "(Small|Medium|Large) Pages:\\s+" + INT + "\\s+" + INT + "\\s+" + INT + "\\s+" + INT + UNITS + "\\s+" + INT + UNITS + "\\s+" + INT + UNITS); + + //[2025-03-07T17:46:50.397-0800][info][gc,reloc ] GC(380) O: Forwarding Usage: 125M + GCParseRule FORWARDING_USAGE_GEN = new GCParseRule("Forwarding Usage",OPT_GEN + "Forwarding Usage: " + INT + UNITS); + + // [2025-03-07T17:49:56.358-0800][info][gc,reloc ] GC(389) y: Live Garbage Small Medium Large + //[2025-03-07T17:49:56.358-0800][info][gc,reloc ] GC(389) y: Eden 234M (0%) 156765M (79%) 78484 / 36719 1 / 0 0 / 0 + //[2025-03-07T17:49:56.358-0800][info][gc,reloc ] GC(389) y: Survivor 1 52M (0%) 649M (0%) 335 / 275 1 / 1 0 / 0 + //[2025-03-07T17:49:56.358-0800][info][gc,reloc ] GC(389) y: Survivor 2 40M (0%) 255M (0%) 148 / 91 0 / 0 0 / 0 + //[2025-03-07T17:49:56.359-0800][info][gc,reloc ] GC(389) y: Survivor 3 38M (0%) 65M (0%) 52 / 20 0 / 0 0 / 0 + GCParseRule AGE_TABLE_GEN = new GCParseRule("Age Table",OPT_GEN + "(Eden|Survivor \\d+)\\s+" + MEMORY_PERCENT + "\\s+" + MEMORY_PERCENT + "\\s+" + INT + " \\/ " + INT + "\\s+" + INT + " \\/ " + INT + "\\s+" + INT + " \\/ " + INT ); + //[3.596s][info ][gc,nmethod ] GC(3) NMethods: 1163 registered, 0 unregistered GCParseRule NMETHODS = new GCParseRule("NMethods",OPT_GEN + " NMethods: " + GenericTokens.INT + " registered, " + GenericTokens.INT + " unregistered"); diff --git a/parser/src/test/java/com/microsoft/gctoolkit/parser/GenerationalZGCParserTest.java b/parser/src/test/java/com/microsoft/gctoolkit/parser/GenerationalZGCParserTest.java index 63d914b6..99efe2e9 100644 --- a/parser/src/test/java/com/microsoft/gctoolkit/parser/GenerationalZGCParserTest.java +++ b/parser/src/test/java/com/microsoft/gctoolkit/parser/GenerationalZGCParserTest.java @@ -6,6 +6,7 @@ import com.microsoft.gctoolkit.event.zgc.MajorZGCCycle; import com.microsoft.gctoolkit.event.zgc.MinorZGCCycle; import com.microsoft.gctoolkit.event.zgc.OccupancySummary; +import com.microsoft.gctoolkit.event.zgc.ZGCPageAgeSummary; import com.microsoft.gctoolkit.event.zgc.ZGCAllocatedSummary; import com.microsoft.gctoolkit.event.zgc.ZGCCompactedSummary; import com.microsoft.gctoolkit.event.zgc.ZGCCycle; @@ -15,6 +16,7 @@ import com.microsoft.gctoolkit.event.zgc.ZGCMemoryPoolSummary; import com.microsoft.gctoolkit.event.zgc.ZGCMemorySummary; import com.microsoft.gctoolkit.event.zgc.ZGCMetaspaceSummary; +import com.microsoft.gctoolkit.event.zgc.ZGCPageSummary; import com.microsoft.gctoolkit.event.zgc.ZGCPromotedSummary; import com.microsoft.gctoolkit.event.zgc.ZGCReclaimSummary; import com.microsoft.gctoolkit.event.zgc.ZGCReferenceSummary; @@ -110,6 +112,11 @@ public void testZgcMajorCycle() { "[2025-02-11T13:06:19.580-0800][info][gc,ref ] GC(1) O: Weak References: 2798 0 0 ", "[2025-02-11T13:06:19.580-0800][info][gc,ref ] GC(1) O: Final References: 719 0 0 ", "[2025-02-11T13:06:19.580-0800][info][gc,ref ] GC(1) O: Phantom References: 497 0 0 ", + "[2025-02-11T13:06:19.580-0800][info][gc,reloc ] GC(1) O: Candidates Selected In-Place Size Empty Relocated", + "[2025-02-11T13:06:19.580-0800][info][gc,reloc ] GC(1) O: Small Pages: 1312 509 0 2624M 2M 103M", + "[2025-02-11T13:06:19.580-0800][info][gc,reloc ] GC(1) O: Medium Pages: 3 2 0 96M 0M 22M", + "[2025-02-11T13:06:19.580-0800][info][gc,reloc ] GC(1) O: Large Pages: 182 0 0 1096M 0M 0M", + "[2025-02-11T13:06:19.580-0800][info][gc,reloc ] GC(1) O: Forwarding Usage: 125M", "[2025-02-11T13:06:19.580-0800][info][gc,heap ] GC(1) O: Min Capacity: 36864M(100%)", "[2025-02-11T13:06:19.580-0800][info][gc,heap ] GC(1) O: Max Capacity: 36864M(100%)", "[2025-02-11T13:06:19.580-0800][info][gc,heap ] GC(1) O: Soft Max Capacity: 36864M(100%)", @@ -187,6 +194,16 @@ public void testZgcMajorCycle() { assertEquals(2335, young.getNMethodSummary().getRegistered()); assertEquals(0, young.getNMethodSummary().getUnregistered()); + assertTrue(checkPageSummary(young.getSmallPageSummary(), 112, 85, 0, 224, 36, 6)); + assertTrue(checkPageSummary(young.getMediumPageSummary(), 2,0,0, 64, 32, 0)); + assertTrue(checkPageSummary(young.getLargePageSummary(), 1,0,0,8,0,0)); + + assertEquals(2, young.getAgeTableSummary().size()); + assertTrue(checkPageAgeSummary(young.getAgeTableSummary().get(0), "Eden", 8, 0, 223, 1, 100, 78, 1, 0, 0,0)); + assertTrue(checkPageAgeSummary(young.getAgeTableSummary().get(1), "Survivor 1", 16, 0 , 47, 0, 12, 7, 1, 0, 1, 0)); + + assertEquals(3 * 1024, young.getForwardingUsage()); + assertEquals(7.61, young.getLoadAverageAt(1)); assertEquals(12.83, young.getLoadAverageAt(5)); assertEquals(13.76, young.getLoadAverageAt(15)); @@ -240,6 +257,12 @@ public void testZgcMajorCycle() { assertTrue(checkZGCMetaSpaceSummary(old.getMetaspaceSummary(),36, 37, 1088)); + assertTrue(checkPageSummary(old.getSmallPageSummary(), 1312, 509, 0, 2624, 2, 103)); + assertTrue(checkPageSummary(old.getMediumPageSummary(), 3,2,0, 96,0, 22)); + assertTrue(checkPageSummary(old.getLargePageSummary(), 182, 0, 0, 1096, 0, 0)); + + assertEquals(125 * 1024, old.getForwardingUsage()); + assertTrue(checkUsedSummary(old.getUsedOccupancySummary(), 0, 0, 0, 0)); assertTrue(checkLiveSummary(old.getLiveSummary(), 0, 0, 0)); assertTrue(checkGarbageSummary(old.getGarbageSummary(), 0, 0, 0)); @@ -378,6 +401,17 @@ public void testZgcMinorCycle() { assertEquals(2335, young.getNMethodSummary().getRegistered()); assertEquals(0, young.getNMethodSummary().getUnregistered()); + assertTrue(checkPageSummary(young.getSmallPageSummary(), 7066, 5720, 0, 14132, 2554, 74)); + assertTrue(checkPageSummary(young.getMediumPageSummary(), 0,0,0,0,0, 0)); + assertTrue(checkPageSummary(young.getLargePageSummary(), 0,0,0,0,0, 0)); + + assertEquals(36 * 1024, young.getForwardingUsage()); + + assertEquals(3, young.getAgeTableSummary().size()); + assertTrue(checkPageAgeSummary(young.getAgeTableSummary().get(0), "Eden", 79, 0 , 13800, 37, 6940, 5622, 0, 0, 0, 0)); + assertTrue(checkPageAgeSummary(young.getAgeTableSummary().get(1), "Survivor 1", 25, 0, 132, 0, 79, 61, 0, 0, 0, 0)); + assertTrue(checkPageAgeSummary(young.getAgeTableSummary().get(2), "Survivor 2", 15, 0, 78, 0, 47, 37, 0, 0, 0, 0)); + assertEquals(17.42, young.getLoadAverageAt(1)); assertEquals(14.37, young.getLoadAverageAt(5)); assertEquals(14.21, young.getLoadAverageAt(15)); @@ -401,12 +435,28 @@ private boolean checkReferenceSummary(ZGCReferenceSummary refSummary, long encou private boolean checkUsedSummary(OccupancySummary summary, long markStart, long markEnd, long relocateStart, long relocateEnd) { return summary.getMarkStart() == (markStart * 1024) && summary.getMarkEnd() == (markEnd * 1024) && summary.getReclaimStart() == (relocateStart * 1024) && summary.getReclaimEnd() == (relocateEnd * 1024); - } private boolean checkDateTimeStampMatch(String expected, double offsetMs, DateTimeStamp dateTimeStamp) { return new DateTimeStamp(expected).minus(offsetMs/1000).compareTo(dateTimeStamp) == 0; } + private boolean checkPageSummary(ZGCPageSummary summary, long candidates, long selected, long inplace, long sizeMb, long emptyMb, long relocatedMb) { + return summary.getCandidates() == candidates && summary.getSelected() == selected && summary.getInPlace() == inplace && summary.getSize() == (sizeMb * 1024L) && summary.getEmpty() == (emptyMb * 1024L) && summary.getRelocated() == (relocatedMb * 1024L); + } + + private boolean checkPageAgeSummary(ZGCPageAgeSummary summary, String name, int liveMb, int livePct, int garbageMb, int garbagePct, int smallCandidates, int smallSelected, int mediumCandidates, int mediumSelected, int largeCandidates, int largeSelected) { + return summary.getName().equals(name) && + summary.getLive() == (1024L * liveMb) && + summary.getLivePct() == livePct && + summary.getGarbage() == (1024L * garbageMb) && + summary.getGarbagePct() == garbagePct && + summary.getSmallPageCandidates() == smallCandidates && + summary.getSmallPageSelected() == smallSelected && + summary.getMediumPageCandidates() == mediumCandidates && + summary.getMediumPageSelected() == mediumSelected && + summary.getLargePageCandidates() == largeCandidates && + summary.getLargePageSelected() == largeSelected; + } private boolean checkZGCMetaSpaceSummary(ZGCMetaspaceSummary summary, long usedMb, long committedMb, long reservedMb) { return summary.getUsed() ==(usedMb * 1024) && summary.getCommitted() == (committedMb * 1024) && summary.getReserved() == (reservedMb * 1024); @@ -416,7 +466,6 @@ private boolean checkZGCHeapSummary(ZGCHeapCapacitySummary summary, long minCapa return summary.getMinCapacity() == (minCapacityMb * 1024) && summary.getMaxCapacity() == (maxCapacityMb * 1024) && summary.getSoftMaxCapacity() == (softMaxCapacityMb * 1024); } - private boolean checkZGCMemoryPoolSummary(ZGCMemoryPoolSummary summary, long capacityMb, long freeMb , long usedMb) { return summary.getCapacity() == (capacityMb * 1024) && summary.getFree() == (freeMb * 1024) && summary.getUsed() == (usedMb * 1024); }