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..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; @@ -250,6 +252,34 @@ public double getMarkFollowDuration() { public ZGCMemoryPoolSummary getRelocateEnd() { return delegate.getRelocateEnd(); } + + public ZGCHeapCapacitySummary getHeapCapacitySummary() { + return delegate.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 cadc8410..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; @@ -57,6 +59,14 @@ public class ZGCCycle { private ZGCReclaimSummary reclaimSummary; private ZGCMemorySummary memorySummary; private ZGCMetaspaceSummary metaspaceSummary; + 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; @@ -493,4 +503,60 @@ 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; + } + + public void setNMethodSummary(ZGCNMethodSummary nMethodSummary) { + this.nMethodSummary = 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/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/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/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 b0f03e18..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,14 +9,18 @@ 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; 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; 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; @@ -35,6 +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; @@ -65,6 +72,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; @@ -95,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); @@ -267,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()); @@ -316,7 +371,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) { @@ -349,7 +409,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 +556,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 +734,7 @@ private static class ZGCForwardReference implements ZForwardReference { // Memory + private ZGCHeapCapacitySummary heapCapacitySummary; private ZGCMemoryPoolSummary markStart; private ZGCMemoryPoolSummary markEnd; private ZGCMemoryPoolSummary relocatedStart; @@ -692,6 +770,12 @@ private static class ZGCForwardReference implements ZForwardReference { private ZGCReferenceSummary weakRefSummary; 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; @@ -758,6 +842,7 @@ public ZGCCycle getZGCCycle(DateTimeStamp endTime) { cycle.setPhantomRefSummary(phantomRefSummary); //Memory + cycle.setHeapCapacitySummary(heapCapacitySummary); cycle.setMarkStart(markStart); cycle.setMarkEnd(markEnd); cycle.setRelocateStart(relocatedStart); @@ -771,10 +856,15 @@ public ZGCCycle getZGCCycle(DateTimeStamp endTime) { cycle.setLoadAverages(load); 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; } - public void setPauseMarkStart(DateTimeStamp pauseMarkStart) { this.pauseMarkStart = pauseMarkStart; } @@ -1005,6 +1095,38 @@ public void setFinalRefSummary(ZGCReferenceSummary finalRefSummary) { public void setPhantomRefSummary(ZGCReferenceSummary phantomRefSummary) { this.phantomRefSummary = phantomRefSummary; } + + public void setHeapCapacitySummary(ZGCHeapCapacitySummary heapCapacitySummary) { + this.heapCapacitySummary = 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 243dd03f..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,14 +6,17 @@ 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; 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; 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; @@ -59,6 +62,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 ", @@ -101,12 +105,18 @@ 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 ", "[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%)", @@ -163,6 +173,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)); @@ -179,6 +191,19 @@ public void testZgcMajorCycle() { assertTrue(checkPromotedSummary(young.getPromotedSummary(), 0, 0)); assertTrue(checkCompactedSummary(young.getCompactedSummary(), 10)); + 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)); @@ -223,6 +248,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)); @@ -230,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)); @@ -239,6 +272,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)); @@ -275,6 +311,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 ", @@ -343,6 +380,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)); @@ -359,6 +398,20 @@ public void testZgcMinorCycle() { assertTrue(checkPromotedSummary(young.getPromotedSummary(), 0, 0)); assertTrue(checkCompactedSummary(young.getCompactedSummary(), 104)); + 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)); @@ -382,17 +435,37 @@ 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); } + 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); }