diff --git a/IT/src/main/java/com/microsoft/gctoolkit/integration/aggregation/CollectionCycleCountsAggregator.java b/IT/src/main/java/com/microsoft/gctoolkit/integration/aggregation/CollectionCycleCountsAggregator.java index ea791bc1..dc34f9db 100644 --- a/IT/src/main/java/com/microsoft/gctoolkit/integration/aggregation/CollectionCycleCountsAggregator.java +++ b/IT/src/main/java/com/microsoft/gctoolkit/integration/aggregation/CollectionCycleCountsAggregator.java @@ -7,9 +7,9 @@ import com.microsoft.gctoolkit.event.g1gc.G1GCPauseEvent; import com.microsoft.gctoolkit.event.generational.GenerationalGCPauseEvent; import com.microsoft.gctoolkit.event.shenandoah.ShenandoahCycle; -import com.microsoft.gctoolkit.event.zgc.FullZGCCycle; -import com.microsoft.gctoolkit.event.zgc.MajorZGCCycle; -import com.microsoft.gctoolkit.event.zgc.MinorZGCCycle; +import com.microsoft.gctoolkit.event.zgc.ZGCFullCollection; +import com.microsoft.gctoolkit.event.zgc.ZGCYoungCollection; +import com.microsoft.gctoolkit.event.zgc.ZGCOldCollection; @Aggregates({EventSource.G1GC,EventSource.GENERATIONAL,EventSource.ZGC,EventSource.SHENANDOAH}) public class CollectionCycleCountsAggregator extends Aggregator { @@ -19,21 +19,21 @@ public CollectionCycleCountsAggregator(CollectionCycleCountsAggregation results) register(GenerationalGCPauseEvent.class, this::count); register(G1GCPauseEvent.class, this::count); register(G1GCConcurrentEvent.class, this::count); - register(FullZGCCycle.class,this::count); - register(MajorZGCCycle.class,this::count); - register(MinorZGCCycle.class,this::count); + register(ZGCFullCollection.class, this::count); + register(ZGCOldCollection.class, this::count); + register(ZGCYoungCollection.class, this::count); register(ShenandoahCycle.class,this::count); } - private void count(FullZGCCycle event) { + private void count(ZGCFullCollection event) { aggregation().count(event.getGarbageCollectionType()); } - private void count(MajorZGCCycle event) { + private void count(ZGCOldCollection event) { aggregation().count(event.getGarbageCollectionType()); } - private void count(MinorZGCCycle event) { + private void count(ZGCYoungCollection event) { aggregation().count(event.getGarbageCollectionType()); } diff --git a/IT/src/main/java/com/microsoft/gctoolkit/integration/aggregation/HeapOccupancyAfterCollectionAggregator.java b/IT/src/main/java/com/microsoft/gctoolkit/integration/aggregation/HeapOccupancyAfterCollectionAggregator.java index d36e7a54..1fede8f0 100644 --- a/IT/src/main/java/com/microsoft/gctoolkit/integration/aggregation/HeapOccupancyAfterCollectionAggregator.java +++ b/IT/src/main/java/com/microsoft/gctoolkit/integration/aggregation/HeapOccupancyAfterCollectionAggregator.java @@ -6,9 +6,9 @@ import com.microsoft.gctoolkit.event.g1gc.G1GCPauseEvent; import com.microsoft.gctoolkit.event.generational.GenerationalGCPauseEvent; import com.microsoft.gctoolkit.event.shenandoah.ShenandoahCycle; -import com.microsoft.gctoolkit.event.zgc.FullZGCCycle; -import com.microsoft.gctoolkit.event.zgc.MajorZGCCycle; -import com.microsoft.gctoolkit.event.zgc.MinorZGCCycle; +import com.microsoft.gctoolkit.event.zgc.ZGCFullCollection; +import com.microsoft.gctoolkit.event.zgc.ZGCOldCollection; +import com.microsoft.gctoolkit.event.zgc.ZGCYoungCollection; @Aggregates({EventSource.G1GC,EventSource.GENERATIONAL,EventSource.ZGC,EventSource.SHENANDOAH}) public class HeapOccupancyAfterCollectionAggregator extends Aggregator { @@ -17,17 +17,17 @@ public HeapOccupancyAfterCollectionAggregator(HeapOccupancyAfterCollectionAggreg super(results); register(GenerationalGCPauseEvent.class, this::extractHeapOccupancy); register(G1GCPauseEvent.class, this::extractHeapOccupancy); - register(FullZGCCycle.class,this::extractHeapOccupancy); - register(MajorZGCCycle.class,this::extractHeapOccupancy); - register(MinorZGCCycle.class,this::extractHeapOccupancy); + register(ZGCFullCollection.class, this::extractHeapOccupancy); + register(ZGCOldCollection.class, this::extractHeapOccupancy); + register(ZGCYoungCollection.class, this::extractHeapOccupancy); register(ShenandoahCycle.class,this::extractHeapOccupancy); } - private void extractHeapOccupancy(MinorZGCCycle event) { - aggregation().addDataPoint(event.getGarbageCollectionType(), event.getDateTimeStamp(), event.getYoungCycle().getMemorySummary().getOccupancyAfter()); + private void extractHeapOccupancy(ZGCYoungCollection event) { + aggregation().addDataPoint(event.getGarbageCollectionType(), event.getDateTimeStamp(), event.getMemorySummary().getOccupancyAfter()); } - private void extractHeapOccupancy(MajorZGCCycle event) { + private void extractHeapOccupancy(ZGCOldCollection event) { aggregation().addDataPoint(event.getGarbageCollectionType(), event.getDateTimeStamp(), event.getMemorySummary().getOccupancyAfter()); } @@ -41,7 +41,7 @@ private void extractHeapOccupancy(G1GCPauseEvent event) { aggregation().addDataPoint(event.getGarbageCollectionType(), event.getDateTimeStamp(), event.getHeap().getOccupancyAfterCollection()); } - private void extractHeapOccupancy(FullZGCCycle event) { + private void extractHeapOccupancy(ZGCFullCollection event) { aggregation().addDataPoint(event.getGarbageCollectionType(), event.getDateTimeStamp(), event.getMemorySummary().getOccupancyAfter()); } diff --git a/api/src/main/java/com/microsoft/gctoolkit/event/GarbageCollectionTypes.java b/api/src/main/java/com/microsoft/gctoolkit/event/GarbageCollectionTypes.java index fc6f6a31..4f184d49 100644 --- a/api/src/main/java/com/microsoft/gctoolkit/event/GarbageCollectionTypes.java +++ b/api/src/main/java/com/microsoft/gctoolkit/event/GarbageCollectionTypes.java @@ -56,8 +56,9 @@ public enum GarbageCollectionTypes implements LabelledGCEventType { G1Trap("G1GC Trap"), Unknown("Unknown"), ZGCFull("ZGC FULL"), - ZGCMajor("ZGC Major"), - ZGCMinor("ZGC Minor"), + ZGCMajorOld("ZGC Major Old"), + ZGCMajorYoung("ZGC Major Young"), + ZGCMinorYoung("ZGC Minor Young"), Shenandoah("Shenandoah"); private final String label; 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 deleted file mode 100644 index a3dc0345..00000000 --- a/api/src/main/java/com/microsoft/gctoolkit/event/zgc/FullZGCCycle.java +++ /dev/null @@ -1,336 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -package com.microsoft.gctoolkit.event.zgc; - -import com.microsoft.gctoolkit.event.GCCause; -import com.microsoft.gctoolkit.event.GCEvent; -import com.microsoft.gctoolkit.event.GarbageCollectionTypes; -import com.microsoft.gctoolkit.time.DateTimeStamp; - -import java.util.List; - -public class FullZGCCycle extends GCEvent { - private ZGCCycle delegate; - - public FullZGCCycle(DateTimeStamp timeStamp, GarbageCollectionTypes gcType, GCCause cause, double duration, ZGCCycle delegate) { - super(timeStamp, gcType, cause, duration); - this.delegate = delegate; - } - - public void setZGCCycle(ZGCCycle zgcCycle) { - this.delegate = zgcCycle; - } - - public ZGCReferenceSummary getSoftRefSummary() { - return delegate.getSoftRefSummary(); - } - - public ZGCReferenceSummary getFinalRefSummary() { - return delegate.getFinalRefSummary(); - } - - public ZGCMemoryPoolSummary getMarkEnd() { - return delegate.getMarkEnd(); - } - - public DateTimeStamp getConcurrentRemapRootsStart() { - return delegate.getConcurrentRemapRootsStart(); - } - - public DateTimeStamp getRemapRememberedStart() { - return delegate.getRemapRememberedStart(); - } - - public ZGCPromotedSummary getPromotedSummary() { - return delegate.getPromotedSummary(); - } - - public ZGCMetaspaceSummary getMetaspaceSummary() { - return delegate.getMetaspaceSummary(); - } - - public ZGCReferenceSummary getWeakRefSummary() { - return delegate.getWeakRefSummary(); - } - - public DateTimeStamp getConcurrentSelectRelocationSetTimeStamp() { - return delegate.getConcurrentSelectRelocationSetTimeStamp(); - } - - public DateTimeStamp getRemapRootColoredStart() { - return delegate.getRemapRootColoredStart(); - } - - public ZGCPhase getPhase() { - return delegate.getPhase(); - } - - public double getRemapRootsColoredDuration() { - return delegate.getRemapRootsColoredDuration(); - } - - public double getConcurrentMarkContinueDuration() { - return delegate.getConcurrentMarkContinueDuration(); - } - - public double getConcurrentRemapRootsDuration() { - return delegate.getConcurrentRemapRootsDuration(); - } - - public double getPauseMarkRelocateDuration() { - return delegate.getPauseMarkRelocateDuration(); - } - - public ZGCAllocatedSummary getAllocatedSummary() { - return delegate.getAllocatedSummary(); - } - - public ZGCReferenceSummary getPhantomRefSummary() { - return delegate.getPhantomRefSummary(); - } - - public ZGCMarkSummary getMarkSummary() { - return delegate.getMarkSummary(); - } - - public double getRemapRememberedDuration() { - return delegate.getRemapRememberedDuration(); - } - - public ZGCGarbageSummary getGarbageSummary() { - return delegate.getGarbageSummary(); - } - - public DateTimeStamp getConcurrentResetRelocationSetTimeStamp() { - return delegate.getConcurrentResetRelocationSetTimeStamp(); - } - - public double getConcurrentMarkFreeDuration() { - return delegate.getConcurrentMarkFreeDuration(); - } - - public ZGCMemoryPoolSummary getMarkStart() { - return delegate.getMarkStart(); - } - - public ZGCLiveSummary getLiveSummary() { - return delegate.getLiveSummary(); - } - - public DateTimeStamp getConcurrentProcessNonStrongReferencesTimeStamp() { - return delegate.getConcurrentProcessNonStrongReferencesTimeStamp(); - } - - public DateTimeStamp getConcurrentMarkContinueTimeStamp() { - return delegate.getConcurrentMarkContinueTimeStamp(); - } - - public ZGCCollectionType getType() { - return delegate.getType(); - } - - public ZGCMemoryPoolSummary getRelocateStart() { - return delegate.getRelocateStart(); - } - - public DateTimeStamp getMarkFollowStart() { - return delegate.getMarkFollowStart(); - } - - public double getPauseMarkEndDuration() { - return delegate.getPauseMarkEndDuration(); - } - - public double getConcurrentSelectRelocationSetDuration() { - return delegate.getConcurrentSelectRelocationSetDuration(); - } - - public double getMarkRootsDuration() { - return delegate.getMarkRootsDuration(); - } - - public double[] getMmu() { - return delegate.getMmu(); - } - - public double getConcurrentProcessNonStrongReferencesDuration() { - return delegate.getConcurrentProcessNonStrongReferencesDuration(); - } - - public DateTimeStamp getConcurrentRelocateTimeStamp() { - return delegate.getConcurrentRelocateTimeStamp(); - } - - public DateTimeStamp getPauseMarkStartTimeStamp() { - return delegate.getPauseMarkStartTimeStamp(); - } - - public double getPauseMarkStartDuration() { - return delegate.getPauseMarkStartDuration(); - } - - public OccupancySummary getUsedOccupancySummary() { - return delegate.getUsedOccupancySummary(); - } - - public DateTimeStamp getConcurrentMarkTimeStamp() { - return delegate.getConcurrentMarkTimeStamp(); - } - - public double getMMU(int percentage) { - return delegate.getMMU(percentage); - } - - public ZGCMemorySummary getMemorySummary() { - return delegate.getMemorySummary(); - } - - public ZGCCompactedSummary getCompactedSummary() { - return delegate.getCompactedSummary(); - } - - public long getGcId() { - return delegate.getGcId(); - } - - public double getConcurrentResetRelocationSetDuration() { - return delegate.getConcurrentResetRelocationSetDuration(); - } - - public DateTimeStamp getConcurrentMarkFreeTimeStamp() { - return delegate.getConcurrentMarkFreeTimeStamp(); - } - - public DateTimeStamp getPauseMarkEndTimeStamp() { - return delegate.getPauseMarkEndTimeStamp(); - } - - public double getConcurrentRelocateDuration() { - return delegate.getConcurrentRelocateDuration(); - } - - public double getLoadAverageAt(int time) { - return delegate.getLoadAverageAt(time); - } - - public DateTimeStamp getPauseRelocateStartTimeStamp() { - return delegate.getPauseRelocateStartTimeStamp(); - } - - public double[] getLoad() { - return delegate.getLoad(); - } - - public double getPauseRelocateStartDuration() { - return delegate.getPauseRelocateStartDuration(); - } - - public DateTimeStamp getRemapRootsUncoloredStart() { - return delegate.getRemapRootsUncoloredStart(); - } - - public DateTimeStamp getMarkRootsStart() { - return delegate.getMarkRootsStart(); - } - - public double getRemapRootsUncoloredDuration() { - return delegate.getRemapRootsUncoloredDuration(); - } - - public double getConcurrentMarkDuration() { - return delegate.getConcurrentMarkDuration(); - } - - public ZGCReclaimSummary getReclaimSummary() { - return delegate.getReclaimSummary(); - } - - public double getMarkFollowDuration() { - return delegate.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 -// Pause mark end duration -// Concurrent reference processing duration -// Concurrent reset relocation set duration -// Concurrent select relocation set duration -// Pause relocate start -// Load -// MMU -// Concurrent relocate -// Relocation volume -// NMethods, registered, unregistered -// Metaspace used, capacity committed, reserved -// Soft, weak, final, phantom.. encountered, discovered, enqueued -// Memory stats - -/* -[32.121s][info][gc,start ] GC(2) Garbage Collection (Metadata GC Threshold) -[32.121s][info][gc,phases ] GC(2) Pause Mark Start 0.023ms -[32.166s][info][gc,phases ] GC(2) Concurrent Mark 44.623ms -[32.166s][info][gc,phases ] GC(2) Pause Mark End 0.029ms -[32.166s][info][gc,phases ] GC(2) Concurrent Mark Free 0.001ms -[32.172s][info][gc,phases ] GC(2) Concurrent Process Non-Strong References 5.797ms -[32.172s][info][gc,phases ] GC(2) Concurrent Reset Relocation Set 0.012ms -[32.178s][info][gc,phases ] GC(2) Concurrent Select Relocation Set 6.446ms -[32.179s][info][gc,phases ] GC(2) Pause Relocate Start 0.024ms -[32.193s][info][gc,phases ] GC(2) Concurrent Relocate 14.013ms -[32.193s][info][gc,load ] GC(2) Load: 7.28/6.63/5.01 -[32.193s][info][gc,mmu ] GC(2) MMU: 2ms/98.2%, 5ms/99.3%, 10ms/99.5%, 20ms/99.7%, 50ms/99.9%, 100ms/99.9% -[32.193s][info][gc,marking ] GC(2) Mark: 4 stripe(s), 3 proactive flush(es), 1 terminate flush(es), 0 completion(s), 0 continuation(s) -[32.193s][info][gc,marking ] GC(2) Mark Stack Usage: 32M -[32.193s][info][gc,metaspace] GC(2) Metaspace: 60M used, 60M committed, 1080M reserved -[32.193s][info][gc,ref ] GC(2) Soft: 5447 encountered, 0 discovered, 0 enqueued -[32.193s][info][gc,ref ] GC(2) Weak: 5347 encountered, 2016 discovered, 810 enqueued -[32.193s][info][gc,ref ] GC(2) Final: 1041 encountered, 113 discovered, 105 enqueued -[32.193s][info][gc,ref ] GC(2) Phantom: 558 encountered, 501 discovered, 364 enqueued -[32.193s][info][gc,reloc ] GC(2) Small Pages: 235 / 470M, Empty: 32M, Relocated: 40M, In-Place: 0 -[32.193s][info][gc,reloc ] GC(2) Medium Pages: 2 / 64M, Empty: 0M, Relocated: 3M, In-Place: 0 -[32.193s][info][gc,reloc ] GC(2) Large Pages: 3 / 24M, Empty: 8M, Relocated: 0M, In-Place: 0 -[32.193s][info][gc,reloc ] GC(2) Forwarding Usage: 13M -[32.193s][info][gc,heap ] GC(2) Min Capacity: 8M(0%) -[32.193s][info][gc,heap ] GC(2) Max Capacity: 28686M(100%) -[32.193s][info][gc,heap ] GC(2) Soft Max Capacity: 28686M(100%) -[32.193s][info][gc,heap ] GC(2) Mark Start Mark End Relocate Start Relocate End High Low -[32.193s][info][gc,heap ] GC(2) Capacity: 1794M (6%) 1794M (6%) 1794M (6%) 1794M (6%) 1794M (6%) 1794M (6%) -[32.193s][info][gc,heap ] GC(2) Free: 28128M (98%) 28110M (98%) 28148M (98%) 28560M (100%) 28560M (100%) 28108M (98%) -[32.193s][info][gc,heap ] GC(2) Used: 558M (2%) 576M (2%) 538M (2%) 126M (0%) 578M (2%) 126M (0%) -[32.193s][info][gc,heap ] GC(2) Live: - 71M (0%) 71M (0%) 71M (0%) - - -[32.193s][info][gc,heap ] GC(2) Allocated: - 18M (0%) 20M (0%) 18M (0%) - - -[32.193s][info][gc,heap ] GC(2) Garbage: - 486M (2%) 446M (2%) 35M (0%) - - -[32.193s][info][gc,heap ] GC(2) Reclaimed: - - 40M (0%) 450M (2%) - - -[32.193s][info][gc ] GC(2) Garbage Collection (Metadata GC Threshold) 558M(2%)->126M(0%) -*/ diff --git a/api/src/main/java/com/microsoft/gctoolkit/event/zgc/MajorZGCCycle.java b/api/src/main/java/com/microsoft/gctoolkit/event/zgc/MajorZGCCycle.java deleted file mode 100644 index 1852c514..00000000 --- a/api/src/main/java/com/microsoft/gctoolkit/event/zgc/MajorZGCCycle.java +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -package com.microsoft.gctoolkit.event.zgc; - -import com.microsoft.gctoolkit.event.GCCause; -import com.microsoft.gctoolkit.event.GCEvent; -import com.microsoft.gctoolkit.event.GarbageCollectionTypes; -import com.microsoft.gctoolkit.time.DateTimeStamp; - -public class MajorZGCCycle extends GCEvent { - private ZGCCycle oldCycle; - private ZGCCycle youngCycle; - private ZGCMemorySummary memorySummary; - private long gcId; - - public MajorZGCCycle(DateTimeStamp timeStamp, GarbageCollectionTypes gcType, GCCause cause, double duration) { - super(timeStamp, gcType, cause, duration); - } - - public MajorZGCCycle(DateTimeStamp timeStamp, double duration) { - super(timeStamp, duration); - } - - public MajorZGCCycle(DateTimeStamp timeStamp, GCCause cause, double duration) { - super(timeStamp, cause, duration); - } - - public MajorZGCCycle(DateTimeStamp timeStamp, GarbageCollectionTypes gcType, double duration) { - super(timeStamp, gcType, duration); - } - - public ZGCCycle getOldCycle() { - return oldCycle; - } - - public void setOldCycle(ZGCCycle oldCycle) { - this.oldCycle = oldCycle; - } - - public ZGCCycle getYoungCycle() { - return youngCycle; - } - - public void setYoungCycle(ZGCCycle youngCycle) { - this.youngCycle = youngCycle; - } - - public ZGCMemorySummary getMemorySummary() { - return memorySummary; - } - - public void setMemorySummary(ZGCMemorySummary memorySummary) { - this.memorySummary = memorySummary; - } - - public void setGcId(long gcId) { - - this.gcId = gcId; - } - - public long getGcId() { - return gcId; - } -} diff --git a/api/src/main/java/com/microsoft/gctoolkit/event/zgc/MinorZGCCycle.java b/api/src/main/java/com/microsoft/gctoolkit/event/zgc/MinorZGCCycle.java deleted file mode 100644 index 1b2d20b1..00000000 --- a/api/src/main/java/com/microsoft/gctoolkit/event/zgc/MinorZGCCycle.java +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -package com.microsoft.gctoolkit.event.zgc; - -import com.microsoft.gctoolkit.event.GCCause; -import com.microsoft.gctoolkit.event.GCEvent; -import com.microsoft.gctoolkit.event.GarbageCollectionTypes; -import com.microsoft.gctoolkit.time.DateTimeStamp; - -public class MinorZGCCycle extends GCEvent { - private ZGCCycle youngCycle; - private ZGCMemorySummary memorySummary; - private long gcId; - - public MinorZGCCycle(DateTimeStamp timeStamp, GarbageCollectionTypes gcType, GCCause cause, double duration) { - super(timeStamp, gcType, cause, duration); - } - - public MinorZGCCycle(DateTimeStamp timeStamp, double duration) { - super(timeStamp, duration); - } - - public MinorZGCCycle(DateTimeStamp timeStamp, GCCause cause, double duration) { - super(timeStamp, cause, duration); - } - - public MinorZGCCycle(DateTimeStamp timeStamp, GarbageCollectionTypes gcType, double duration) { - super(timeStamp, gcType, duration); - } - - public ZGCCycle getYoungCycle() { - return youngCycle; - } - - public void setYoungCycle(ZGCCycle youngCycle) { - this.youngCycle = youngCycle; - } - - public ZGCMemorySummary getMemorySummary() { - return memorySummary; - } - - public void setMemorySummary(ZGCMemorySummary memorySummary) { - this.memorySummary = memorySummary; - } - - public void setGcId(long gcId) { - - this.gcId = gcId; - } - - public long getGcId() { - return gcId; - } -} diff --git a/api/src/main/java/com/microsoft/gctoolkit/event/zgc/ZGCCycle.java b/api/src/main/java/com/microsoft/gctoolkit/event/zgc/ZGCCollection.java similarity index 93% rename from api/src/main/java/com/microsoft/gctoolkit/event/zgc/ZGCCycle.java rename to api/src/main/java/com/microsoft/gctoolkit/event/zgc/ZGCCollection.java index d06173f8..e14e959b 100644 --- a/api/src/main/java/com/microsoft/gctoolkit/event/zgc/ZGCCycle.java +++ b/api/src/main/java/com/microsoft/gctoolkit/event/zgc/ZGCCollection.java @@ -1,10 +1,13 @@ package com.microsoft.gctoolkit.event.zgc; +import com.microsoft.gctoolkit.event.GCCause; +import com.microsoft.gctoolkit.event.GCEvent; +import com.microsoft.gctoolkit.event.GarbageCollectionTypes; import com.microsoft.gctoolkit.time.DateTimeStamp; import java.util.List; -public class ZGCCycle { +public class ZGCCollection extends GCEvent { private DateTimeStamp markRootsStart; private double markRootsDuration; private DateTimeStamp markFollowStart; @@ -18,9 +21,9 @@ public class ZGCCycle { private ZGCMarkSummary markSummary; private ZGCPromotedSummary promotedSummary; private ZGCCompactedSummary compactedSummary; - private ZGCCollectionType type; + private ZGCCycleType type; private ZGCPhase phase; - private OccupancySummary usedOccupancySummary; + private OccupancySummary generationUsedSummary; private long gcId; private DateTimeStamp pauseMarkStartTimeStamp; private double pauseMarkStartDuration; @@ -68,6 +71,24 @@ public class ZGCCycle { private long forwardingUsage; private List ageTableSummary; + public ZGCCollection(DateTimeStamp timeStamp, GarbageCollectionTypes gcType, GCCause cause, double duration) { + super(timeStamp, gcType, cause, duration); + } + + public ZGCCollection(DateTimeStamp timeStamp, double duration) { + super(timeStamp, duration); + } + + public ZGCCollection(DateTimeStamp timeStamp, GCCause cause, double duration) { + super(timeStamp, cause, duration); + } + + public ZGCCollection(DateTimeStamp timeStamp, GarbageCollectionTypes gcType, double duration) { + super(timeStamp, gcType, duration); + } + + + public ZGCReferenceSummary getSoftRefSummary() { return softRefSummary; } @@ -395,20 +416,20 @@ public void setCompactedSummary(ZGCCompactedSummary compactedSummary) { this.compactedSummary = compactedSummary; } - public void setusedOccupancySummary(OccupancySummary usedOccupancySummary) { + public void setGenerationUsedSummary(OccupancySummary usedOccupancySummary) { - this.usedOccupancySummary = usedOccupancySummary; + this.generationUsedSummary = usedOccupancySummary; } - public OccupancySummary getUsedOccupancySummary() { - return usedOccupancySummary; + public OccupancySummary getGenerationUsedSummary() { + return generationUsedSummary; } - public ZGCCollectionType getType() { + public ZGCCycleType getType() { return type; } - public void setType(ZGCCollectionType type) { + public void setType(ZGCCycleType type) { this.type = type; } diff --git a/api/src/main/java/com/microsoft/gctoolkit/event/zgc/ZGCCollectionType.java b/api/src/main/java/com/microsoft/gctoolkit/event/zgc/ZGCCollectionType.java deleted file mode 100644 index 38838afc..00000000 --- a/api/src/main/java/com/microsoft/gctoolkit/event/zgc/ZGCCollectionType.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.microsoft.gctoolkit.event.zgc; - -import java.util.Arrays; -import java.util.Objects; - -public enum ZGCCollectionType { - FULL("Garbage"), // Legacy ZGC - MINOR("Minor"), - MAJOR("Major"); - - private final String collectionLabel; - - ZGCCollectionType(String collectionLabel) { - this.collectionLabel = collectionLabel; - } - - public static ZGCCollectionType get(String label) { - return Arrays.stream(ZGCCollectionType.class.getEnumConstants()) - .filter(collectionType -> Objects.equals(collectionType.collectionLabel, label)) - .findFirst() - .orElse(null); - } -} diff --git a/api/src/main/java/com/microsoft/gctoolkit/event/zgc/ZGCCycleType.java b/api/src/main/java/com/microsoft/gctoolkit/event/zgc/ZGCCycleType.java new file mode 100644 index 00000000..945e8d6a --- /dev/null +++ b/api/src/main/java/com/microsoft/gctoolkit/event/zgc/ZGCCycleType.java @@ -0,0 +1,35 @@ +package com.microsoft.gctoolkit.event.zgc; + +import java.util.Arrays; +import java.util.Objects; + +public enum ZGCCycleType { + FULL("Garbage"), // Legacy ZGC + MINOR("Minor"), + MAJOR("Major"); + + private final String cycleLabel; + + ZGCCycleType(String cycleLabel) { + this.cycleLabel = cycleLabel; + } + + public static ZGCCycleType get(String label) { + return Arrays.stream(ZGCCycleType.class.getEnumConstants()) + .filter(collectionType -> Objects.equals(collectionType.cycleLabel, label)) + .findFirst() + .orElse(null); + } + + public static ZGCCycleType fromPhase(ZGCPhase phase){ + if(phase == ZGCPhase.FULL){ + return ZGCCycleType.FULL; + } else if (phase == ZGCPhase.MAJOR_YOUNG || phase == ZGCPhase.MAJOR_OLD){ + return ZGCCycleType.MAJOR; + } else if (phase == ZGCPhase.MINOR_YOUNG){ + return ZGCCycleType.MINOR; + } else { + throw new IllegalArgumentException(String.format("Unknown ZGCPhase: %s", phase)); + } + } +} diff --git a/api/src/main/java/com/microsoft/gctoolkit/event/zgc/ZGCFullCollection.java b/api/src/main/java/com/microsoft/gctoolkit/event/zgc/ZGCFullCollection.java new file mode 100644 index 00000000..ff359ffc --- /dev/null +++ b/api/src/main/java/com/microsoft/gctoolkit/event/zgc/ZGCFullCollection.java @@ -0,0 +1,23 @@ +package com.microsoft.gctoolkit.event.zgc; + +import com.microsoft.gctoolkit.event.GCCause; +import com.microsoft.gctoolkit.event.GarbageCollectionTypes; +import com.microsoft.gctoolkit.time.DateTimeStamp; + +public class ZGCFullCollection extends ZGCCollection { + public ZGCFullCollection(DateTimeStamp timeStamp, GarbageCollectionTypes gcType, GCCause cause, double duration) { + super(timeStamp, gcType, cause, duration); + } + + public ZGCFullCollection(DateTimeStamp timeStamp, double duration) { + super(timeStamp, duration); + } + + public ZGCFullCollection(DateTimeStamp timeStamp, GCCause cause, double duration) { + super(timeStamp, cause, duration); + } + + public ZGCFullCollection(DateTimeStamp timeStamp, GarbageCollectionTypes gcType, double duration) { + super(timeStamp, gcType, duration); + } +} diff --git a/api/src/main/java/com/microsoft/gctoolkit/event/zgc/ZGCOldCollection.java b/api/src/main/java/com/microsoft/gctoolkit/event/zgc/ZGCOldCollection.java new file mode 100644 index 00000000..059f1cf1 --- /dev/null +++ b/api/src/main/java/com/microsoft/gctoolkit/event/zgc/ZGCOldCollection.java @@ -0,0 +1,23 @@ +package com.microsoft.gctoolkit.event.zgc; + +import com.microsoft.gctoolkit.event.GCCause; +import com.microsoft.gctoolkit.event.GarbageCollectionTypes; +import com.microsoft.gctoolkit.time.DateTimeStamp; + +public class ZGCOldCollection extends ZGCCollection { + public ZGCOldCollection(DateTimeStamp timeStamp, GarbageCollectionTypes gcType, GCCause cause, double duration) { + super(timeStamp, gcType, cause, duration); + } + + public ZGCOldCollection(DateTimeStamp timeStamp, double duration) { + super(timeStamp, duration); + } + + public ZGCOldCollection(DateTimeStamp timeStamp, GCCause cause, double duration) { + super(timeStamp, cause, duration); + } + + public ZGCOldCollection(DateTimeStamp timeStamp, GarbageCollectionTypes gcType, double duration) { + super(timeStamp, gcType, duration); + } +} diff --git a/api/src/main/java/com/microsoft/gctoolkit/event/zgc/ZGCYoungCollection.java b/api/src/main/java/com/microsoft/gctoolkit/event/zgc/ZGCYoungCollection.java new file mode 100644 index 00000000..d4c77205 --- /dev/null +++ b/api/src/main/java/com/microsoft/gctoolkit/event/zgc/ZGCYoungCollection.java @@ -0,0 +1,23 @@ +package com.microsoft.gctoolkit.event.zgc; + +import com.microsoft.gctoolkit.event.GCCause; +import com.microsoft.gctoolkit.event.GarbageCollectionTypes; +import com.microsoft.gctoolkit.time.DateTimeStamp; + +public class ZGCYoungCollection extends ZGCCollection { + public ZGCYoungCollection(DateTimeStamp timeStamp, GarbageCollectionTypes gcType, GCCause cause, double duration) { + super(timeStamp, gcType, cause, duration); + } + + public ZGCYoungCollection(DateTimeStamp timeStamp, double duration) { + super(timeStamp, duration); + } + + public ZGCYoungCollection(DateTimeStamp timeStamp, GCCause cause, double duration) { + super(timeStamp, cause, duration); + } + + public ZGCYoungCollection(DateTimeStamp timeStamp, GarbageCollectionTypes gcType, double duration) { + super(timeStamp, gcType, duration); + } +} diff --git a/api/src/main/java/com/microsoft/gctoolkit/jvm/Diary.java b/api/src/main/java/com/microsoft/gctoolkit/jvm/Diary.java index 5ecdcdbe..d43522d1 100644 --- a/api/src/main/java/com/microsoft/gctoolkit/jvm/Diary.java +++ b/api/src/main/java/com/microsoft/gctoolkit/jvm/Diary.java @@ -50,6 +50,8 @@ TLAB_DATA, // 25 PRINT_PROMOTION_FAILURE, // 26 PRINT_FLS_STATISTICS // 27 + PRINT_CPU_TIMES // 28 + GENERATIONAL_ZGC // 29 */ public class Diary { @@ -174,6 +176,10 @@ public boolean isZGC() { return isTrue(SupportedFlags.ZGC); } + public boolean isGenerationalZGC(){ + return isTrue(SupportedFlags.GENERATIONAL_ZGC); + } + public boolean isShenandoah() { return isTrue(SupportedFlags.SHENANDOAH); } diff --git a/api/src/main/java/com/microsoft/gctoolkit/jvm/SupportedFlags.java b/api/src/main/java/com/microsoft/gctoolkit/jvm/SupportedFlags.java index 2f5d9f8a..f58b71c2 100644 --- a/api/src/main/java/com/microsoft/gctoolkit/jvm/SupportedFlags.java +++ b/api/src/main/java/com/microsoft/gctoolkit/jvm/SupportedFlags.java @@ -37,6 +37,8 @@ public enum SupportedFlags { PRINT_PROMOTION_FAILURE, // 26 PRINT_FLS_STATISTICS, // 27 - PRINT_CPU_TIMES // 28 + PRINT_CPU_TIMES, // 28 + + GENERATIONAL_ZGC, // 29 } diff --git a/parser/src/main/java/com/microsoft/gctoolkit/parser/GCLogTrace.java b/parser/src/main/java/com/microsoft/gctoolkit/parser/GCLogTrace.java index 9607d284..40f210f2 100644 --- a/parser/src/main/java/com/microsoft/gctoolkit/parser/GCLogTrace.java +++ b/parser/src/main/java/com/microsoft/gctoolkit/parser/GCLogTrace.java @@ -11,15 +11,12 @@ import com.microsoft.gctoolkit.event.UnifiedStatisticalSummary; import com.microsoft.gctoolkit.event.jvm.MetaspaceRecord; import com.microsoft.gctoolkit.event.jvm.PermGenSummary; -import com.microsoft.gctoolkit.event.zgc.ZGCCollectionType; import com.microsoft.gctoolkit.event.zgc.ZGCPhase; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Matcher; -import static com.microsoft.gctoolkit.event.zgc.ZGCPhase.FULL; - /** * Class that represents a chunk of GC log that we are attempting to match to a * known GC log pattern 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 cad0aaf9..2083157f 100644 --- a/parser/src/main/java/com/microsoft/gctoolkit/parser/ZGCParser.java +++ b/parser/src/main/java/com/microsoft/gctoolkit/parser/ZGCParser.java @@ -10,22 +10,22 @@ 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.ZGCFullCollection; +import com.microsoft.gctoolkit.event.zgc.ZGCYoungCollection; +import com.microsoft.gctoolkit.event.zgc.ZGCOldCollection; 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; -import com.microsoft.gctoolkit.event.zgc.ZGCCollectionType; -import com.microsoft.gctoolkit.event.zgc.ZGCCycle; +import com.microsoft.gctoolkit.event.zgc.ZGCCycleType; +import com.microsoft.gctoolkit.event.zgc.ZGCCollection; import com.microsoft.gctoolkit.event.zgc.ZGCMarkSummary; import com.microsoft.gctoolkit.event.zgc.ZGCMemoryPoolSummary; import com.microsoft.gctoolkit.event.zgc.ZGCMetaspaceSummary; @@ -44,6 +44,7 @@ import java.util.List; import java.util.Optional; import java.util.Set; +import java.util.HashMap; import java.util.function.BiConsumer; import java.util.logging.Level; import java.util.logging.Logger; @@ -66,17 +67,13 @@ public class ZGCParser extends UnifiedGCLogParser implements ZGCPatterns { private final boolean debugging = Boolean.getBoolean("microsoft.debug"); private final boolean develop = Boolean.getBoolean("microsoft.develop"); - private ZForwardReference forwardReference; + private final ZGCForwardReference[] forwardReferences = new ZGCForwardReference[3]; + private final HashMap gcCauseMap = new HashMap<>(2); - private final long[] markStart = new long[3]; - 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; - private boolean youngGenHeapStats = false; + private boolean genHeapStats = false; //Implement all capture methods { @@ -102,14 +99,13 @@ public class ZGCParser extends UnifiedGCLogParser implements ZGCPatterns { // Generation ("gen") ZGC only options parseRules.put(LOAD_GEN, this::loadGen); parseRules.put(REFERENCE_PROCESSING_GEN, this::referenceProcessingGen); - parseRules.put(END_OF_PHASE_SUMMARY_GEN, this::endOfPhaseMemorySummary); + parseRules.put(END_OF_PHASE_SUMMARY_GEN, this::generationEnd); parseRules.put(PAGES_GEN, this::pageSummary); parseRules.put(FORWARDING_USAGE_GEN, this::forwardingUsage); parseRules.put(AGE_TABLE_GEN, this::ageTable); + parseRules.put(GENERATION_START, this::generationStart); - // Phase change rules - parseRules.put(MARK_OLD_GEN_HEAP_STATS, this::markOldGenHeapStats); - parseRules.put(MARK_YOUNG_GEN_HEAP_STATS, this::markYoungGenHeapStats); + parseRules.put(MARK_GEN_HEAP_STATS, this::markGenHeapStats); } public ZGCParser() {} @@ -123,21 +119,10 @@ public Set eventsProduced() { * This marks the phase we're in for memory stats. Generation ZGC will provide heap capacity * as well as old and young gen capacities. This enables the Young gen phase */ - private void markYoungGenHeapStats(GCLogTrace gcLogTrace, String s) { - this.youngGenHeapStats = true; - this.oldGenHeapStats = false; + private void markGenHeapStats(GCLogTrace gcLogTrace, String s) { + this.genHeapStats = true; } - /** - * This marks the phase we're in for memory stats. Generation ZGC will provide heap capacity - * as well as old and young gen capacities. This enables the Old gen phase - */ - private void markOldGenHeapStats(GCLogTrace gcLogTrace, String s) { - this.youngGenHeapStats = false; - this.oldGenHeapStats = true; - } - - @Override public String getName() { return "ZGC Parser"; @@ -178,38 +163,66 @@ private ZGCForwardReference getForwardRefForPhase(ZGCPhase zgcPhase) { switch (zgcPhase) { // No phase information, legacy ZGC case FULL: - return (ZGCForwardReference) forwardReference; + return forwardReferences[0]; case MAJOR_YOUNG: - return ((ZGCMajorForwardReference)forwardReference).getYoungGeneration(); - case MAJOR_OLD: - return ((ZGCMajorForwardReference)forwardReference).getOldGeneration(); case MINOR_YOUNG: - return ((ZGCMinorForwardReference)forwardReference).getYoungGeneration(); + return forwardReferences[1]; + case MAJOR_OLD: + return forwardReferences[2]; + default: + throw new RuntimeException("Unknown phase " + zgcPhase); } - - // Should never reach (should convert to switch expression) - throw new RuntimeException("Unknown phase " + zgcPhase); } - private void cycleStart(GCLogTrace trace, String s) { - ZGCCollectionType type = ZGCCollectionType.get(trace.getGroup(2)); - - switch (type) { + private void setForwardRefForPhase(ZGCPhase zgcPhase, ZGCForwardReference forwardReference){ + switch (zgcPhase) { + // No phase information, legacy ZGC case FULL: - // FULL, Legacy ZGC - forwardReference = new ZGCForwardReference(getClock(), trace.getLongGroup(1), trace.gcCause(3,0), type, ZGCPhase.FULL); + forwardReferences[0] = forwardReference; break; - case MINOR: - // MINOR, young only collection - forwardReference = new ZGCMinorForwardReference(getClock(), trace.getLongGroup(1), trace.gcCause(3,0), type); + case MAJOR_YOUNG: + case MINOR_YOUNG: + forwardReferences[1] = forwardReference; break; - case MAJOR: - // MAJOR, young and old gen collection - forwardReference = new ZGCMajorForwardReference(getClock(), trace.getLongGroup(1), trace.gcCause(3,0), type); + case MAJOR_OLD: + forwardReferences[2] = forwardReference; break; + default: + throw new RuntimeException("Unknown phase " + zgcPhase); + } + } + + private void cycleStart(GCLogTrace trace, String s) { + ZGCCycleType type = ZGCCycleType.get(trace.getGroup(2)); + if(type == ZGCCycleType.FULL){ + setForwardRefForPhase( + ZGCPhase.FULL, + new ZGCForwardReference(getClock(), trace.getLongGroup(1), trace.gcCause(3,0), type, ZGCPhase.FULL) + ); + } + else { + // The cycle start message gives us the gc cause, which we need to create the GCEvent in generationStart + // When we get a cycle start, store the gc cause for later use + gcCauseMap.put(trace.getLongGroup(1), trace.gcCause(1, 2)); } } + private void generationStart(GCLogTrace trace, String line){ + if(!diary.isGenerationalZGC()){ + LOGGER.severe("generationStart rule was matched, but log file isn't generational ZGC. This should be impossible."); + return; + } + ZGCPhase phase = ZGCPhase.get(trace.getGroup(2)); + long gcId = trace.getLongGroup(1); + GCCause gcCause = gcCauseMap.getOrDefault(gcId, GCCause.UNKNOWN_GCCAUSE); + ZGCForwardReference forwardReference = new ZGCForwardReference(getClock(), gcId, gcCause, ZGCCycleType.fromPhase(phase), phase); + setForwardRefForPhase( + phase, + forwardReference + ); + } + + private void pausePhase(GCLogTrace trace, String s) { ZGCForwardReference ref = getForwardRefForPhase(trace.getZCollectionPhase()); @@ -421,26 +434,25 @@ private void capacity(GCLogTrace trace, String s) { } } - private void captureAtIndex(GCLogTrace trace, int index) { - // temporary holder of marking info to get set on fwdref - markStart[index] = trace.toKBytes(3); - markEnd[index] = trace.toKBytes(6); - relocateStart[index] = trace.toKBytes(9); - relocateEnd[index] = trace.toKBytes(12); + private void captureAtIndex(GCLogTrace trace, int index, ZGCMemoryPoolSummaryBuilder memoryPoolSummaryBuilder) { + memoryPoolSummaryBuilder.setMarkStart(index, trace.toKBytes(3)); + memoryPoolSummaryBuilder.setMarkEnd(index, trace.toKBytes(6)); + memoryPoolSummaryBuilder.setRelocateStart(index, trace.toKBytes(9)); + memoryPoolSummaryBuilder.setRelocateEnd(index, trace.toKBytes(12)); } private void sizeEntry(GCLogTrace trace, String s) { ZGCPhase phase = trace.getZCollectionPhase(); ZGCForwardReference ref = getForwardRefForPhase(phase); - if (oldGenHeapStats || youngGenHeapStats) { + if (genHeapStats) { if ("Used".equals(trace.getGroup(2))){ OccupancySummary summary = new OccupancySummary( trace.toKBytes(3), trace.toKBytes(6), trace.toKBytes(9), trace.toKBytes(12)); - ref.setUsed(phase, summary); + ref.setGenerationUsedSummary(phase, summary); } else { trace.notYetImplemented(); } @@ -449,16 +461,17 @@ private void sizeEntry(GCLogTrace trace, String s) { switch (trace.getGroup(2)) { case "Capacity": - captureAtIndex(trace, 0); + captureAtIndex(trace, 0, ref.memoryPoolSummaryBuilder); break; case "Free": - captureAtIndex(trace, 1); + captureAtIndex(trace, 1, ref.memoryPoolSummaryBuilder); break; case "Used": - ref.setMarkStart(new ZGCMemoryPoolSummary(markStart[0], markStart[1], trace.toKBytes(3))); - ref.setMarkEnd(new ZGCMemoryPoolSummary(markEnd[0], markEnd[1], trace.toKBytes(6))); - ref.setRelocateStart(new ZGCMemoryPoolSummary(relocateStart[0], relocateStart[1], trace.toKBytes(9))); - ref.setRelocateEnd(new ZGCMemoryPoolSummary(relocateEnd[0], relocateEnd[1], trace.toKBytes(12))); + captureAtIndex(trace, 2, ref.memoryPoolSummaryBuilder); + ref.setMarkStart(ref.memoryPoolSummaryBuilder.buildMarkStart()); + ref.setMarkEnd(ref.memoryPoolSummaryBuilder.buildMarkEnd()); + ref.setRelocateStart(ref.memoryPoolSummaryBuilder.buildRelocateStart()); + ref.setRelocateEnd(ref.memoryPoolSummaryBuilder.buildRelocateEnd()); break; default: LOGGER.warning(trace.getGroup(2) + "not recognized, Heap Occupancy/size is is ignored. Please report this with the GC log"); @@ -510,9 +523,8 @@ private void reclaimedPromoted(GCLogTrace trace, String s) { private void compacted(GCLogTrace trace, String s) { ZGCForwardReference ref = getForwardRefForPhase(trace.getZCollectionPhase()); - // Exit both young and old gen stats, reset for next cycle - this.oldGenHeapStats = false; - this.youngGenHeapStats = false; + // Exit gen stats, reset for next cycle + this.genHeapStats = false; ref.setCompactedSummary( new ZGCCompactedSummary( trace.toKBytes(2) @@ -520,9 +532,10 @@ private void compacted(GCLogTrace trace, String s) { ); } - private void endOfPhaseMemorySummary(GCLogTrace trace, String s) { + private void generationEnd(GCLogTrace trace, String s) { ZGCForwardReference ref = getForwardRefForPhase(trace.getZCollectionPhase()); + genHeapStats = false; ref.setMemorySummary( new ZGCMemorySummary( trace.toKBytes(3), @@ -531,42 +544,24 @@ private void endOfPhaseMemorySummary(GCLogTrace trace, String s) { if (trace.getGroup(9) != null) { ref.setGcDuration(trace.getSeconds(9)); } + + publish(ref.getGCEVent(getClock())); } private void memorySummary(GCLogTrace trace, String s) { - ZGCCollectionType type = ZGCCollectionType.get(trace.getGroup(1)); - switch (type) { - case FULL: - ((ZGCForwardReference)forwardReference).setMemorySummary( + if(diary.isGenerationalZGC()){ + long gcId = trace.getLongGroup(1); + gcCauseMap.remove(gcId); + } else { + ZGCForwardReference forwardReference = getForwardRefForPhase(ZGCPhase.FULL); + forwardReference.setMemorySummary( new ZGCMemorySummary( - trace.toKBytes(3), - trace.toKBytes(6))); - break; - case MINOR: - ((ZGCMinorForwardReference)forwardReference).setMemorySummary( - new ZGCMemorySummary( - trace.toKBytes(3), - trace.toKBytes(6))); - break; - case MAJOR: - ((ZGCMajorForwardReference)forwardReference).setMemorySummary( - new ZGCMemorySummary( - trace.toKBytes(3), - trace.toKBytes(6))); - break; + trace.toKBytes(4), + trace.toKBytes(7))); + publish(forwardReference.getGCEVent(getClock())); } - - // Clean up / reset temp variables - Arrays.fill(markStart, 0L); - Arrays.fill(markEnd, 0L); - Arrays.fill(relocateStart, 0L); - Arrays.fill(relocateEnd, 0L); + // TODO - Get rid of this? Arrays.fill(heapCapacity, 0L); - oldGenHeapStats = false; - youngGenHeapStats = false; - - // TODO: Consider using logging cycle duration instead of timestamps - publish(); } @@ -580,132 +575,54 @@ public void logMissedFirstRecordForEvent(String line) { LOGGER.log(Level.WARNING, "Missing initial record for: {0}", line); } - public void publish() { - publish(forwardReference.getGCEVent(getClock())); - } - public void publish(JVMEvent event) { super.publish(ChannelName.ZGC_PARSER_OUTBOX, event); - forwardReference = null; - } - - private interface ZForwardReference { - GCEvent getGCEVent(DateTimeStamp endTime); } - private static class ZGCMinorForwardReference implements ZForwardReference { - private final DateTimeStamp startTimeStamp; - private final GCCause gcCause; - private final ZGCCollectionType type; - private final long gcId; - private ZGCMemorySummary cycleMemorySummary; - - // Holds single reference to minor collection stats - private ZGCForwardReference youngGeneration; - - public ZGCMinorForwardReference(DateTimeStamp dateTimeStamp, long gcId, GCCause cause, ZGCCollectionType type) { - this.startTimeStamp = dateTimeStamp; - this.gcCause = cause; - this.type = type; - this.gcId = gcId; + private static class ZGCMemoryPoolSummaryBuilder { + private final long[] markStart = new long[3]; + private final long[] markEnd = new long[3]; + private final long[] relocateStart = new long[3]; + private final long[] relocateEnd = new long[3]; - youngGeneration = new ZGCForwardReference(dateTimeStamp, gcId, cause, type, ZGCPhase.MINOR_YOUNG); + public void setMarkStart(int index, long value){ + markStart[index] = value; } - public ZGCForwardReference getYoungGeneration() { - return youngGeneration; + public void setMarkEnd(int index, long value){ + markEnd[index] = value; } - @Override - public GCEvent getGCEVent(DateTimeStamp endTime) { - GarbageCollectionTypes gcType = GarbageCollectionTypes.Unknown; - switch (type) { - case FULL: - gcType = GarbageCollectionTypes.ZGCFull; - break; - case MINOR: - gcType = GarbageCollectionTypes.ZGCMinor; - break; - case MAJOR: - gcType = GarbageCollectionTypes.ZGCMajor; - break; - } - - MinorZGCCycle cycle = new MinorZGCCycle(startTimeStamp, gcType, gcCause, endTime.minus(startTimeStamp)); - cycle.setYoungCycle(youngGeneration.getZGCCycle(endTime)); - cycle.setMemorySummary(cycleMemorySummary); - cycle.setGcId(gcId); - - return cycle; + public void setRelocateStart(int index, long value){ + relocateStart[index] = value; } - public void setMemorySummary(ZGCMemorySummary cycleMemorySummary) { - this.cycleMemorySummary = cycleMemorySummary; + public void setRelocateEnd(int index, long value){ + relocateEnd[index] = value; } - } - - private static class ZGCMajorForwardReference implements ZForwardReference { - private final DateTimeStamp startTimeStamp; - private final GCCause gcCause; - private final ZGCCollectionType type; - private final long gcId; - private ZGCMemorySummary cycleMemorySummary; - - // Holds two references to minor and major collection stats - private final ZGCForwardReference youngGeneration; - private final ZGCForwardReference oldGeneration; - public ZGCMajorForwardReference(DateTimeStamp dateTimeStamp, long gcId, GCCause cause, ZGCCollectionType type) { - this.startTimeStamp = dateTimeStamp; - this.gcCause = cause; - this.type = type; - this.gcId = gcId; - - youngGeneration = new ZGCForwardReference(dateTimeStamp, gcId, cause, type, ZGCPhase.MAJOR_YOUNG); - oldGeneration = new ZGCForwardReference(dateTimeStamp, gcId, cause, type, ZGCPhase.MAJOR_OLD); + public ZGCMemoryPoolSummary buildMarkStart(){ + return new ZGCMemoryPoolSummary(markStart[0], markStart[1], markStart[2]); } - public ZGCForwardReference getYoungGeneration() { - return youngGeneration; + public ZGCMemoryPoolSummary buildMarkEnd(){ + return new ZGCMemoryPoolSummary(markEnd[0], markEnd[1], markEnd[2]); } - public ZGCForwardReference getOldGeneration() { - return oldGeneration; + public ZGCMemoryPoolSummary buildRelocateStart(){ + return new ZGCMemoryPoolSummary(relocateStart[0], relocateStart[1], relocateStart[2]); } - public void setMemorySummary(ZGCMemorySummary cycleMemorySummary) { - this.cycleMemorySummary = cycleMemorySummary; + public ZGCMemoryPoolSummary buildRelocateEnd(){ + return new ZGCMemoryPoolSummary(relocateEnd[0], relocateEnd[1], relocateEnd[2]); } - @Override - public GCEvent getGCEVent(DateTimeStamp endTime) { - GarbageCollectionTypes gcType = GarbageCollectionTypes.Unknown; - switch (type) { - case FULL: - gcType = GarbageCollectionTypes.ZGCFull; - break; - case MINOR: - gcType = GarbageCollectionTypes.ZGCMinor; - break; - case MAJOR: - gcType = GarbageCollectionTypes.ZGCMajor; - break; - } - - MajorZGCCycle cycle = new MajorZGCCycle(startTimeStamp, gcType, gcCause, endTime.minus(startTimeStamp)); - cycle.setYoungCycle(youngGeneration.getZGCCycle(endTime)); - cycle.setOldCycle(oldGeneration.getZGCCycle(endTime)); - cycle.setMemorySummary(cycleMemorySummary); - cycle.setGcId(gcId); - - return cycle; - } } - private static class ZGCForwardReference implements ZForwardReference { + private static class ZGCForwardReference { private final DateTimeStamp startTimeStamp; private final GCCause gcCause; - private final ZGCCollectionType type; + private final ZGCCycleType type; private final ZGCPhase phase; private final long gcId; @@ -765,7 +682,7 @@ private static class ZGCForwardReference implements ZForwardReference { private ZGCPromotedSummary promotedSummary; private ZGCCompactedSummary compactedSummary; private Double gcDuration; - private OccupancySummary usedOccupancySummary; + private OccupancySummary generationUsedSummary; private ZGCReferenceSummary softRefSummary; private ZGCReferenceSummary weakRefSummary; private ZGCReferenceSummary finalRefSummary; @@ -776,44 +693,38 @@ private static class ZGCForwardReference implements ZForwardReference { private ZGCPageSummary largePageSummary; private long forwardingUsage; private List ageTableSummary; + private final ZGCMemoryPoolSummaryBuilder memoryPoolSummaryBuilder; - public ZGCForwardReference(DateTimeStamp dateTimeStamp, long gcId, GCCause cause, ZGCCollectionType type, ZGCPhase phase) { + public ZGCForwardReference(DateTimeStamp dateTimeStamp, long gcId, GCCause cause, ZGCCycleType type, ZGCPhase phase) { this.startTimeStamp = dateTimeStamp; this.gcId = gcId; this.gcCause = cause; this.type = type; this.phase = phase; + this.memoryPoolSummaryBuilder = new ZGCMemoryPoolSummaryBuilder(); } - @Override public GCEvent getGCEVent(DateTimeStamp endTime) { - GarbageCollectionTypes gcType = GarbageCollectionTypes.Unknown; - switch (type) { + ZGCCollection cycle; + double duration = (gcDuration != null) ? gcDuration : endTime.minus(startTimeStamp); + + switch (phase) { case FULL: - gcType = GarbageCollectionTypes.ZGCFull; + cycle = new ZGCFullCollection(startTimeStamp, GarbageCollectionTypes.ZGCFull, gcCause, duration); break; - case MINOR: - gcType = GarbageCollectionTypes.ZGCMinor; + case MINOR_YOUNG: + cycle = new ZGCYoungCollection(startTimeStamp, GarbageCollectionTypes.ZGCMinorYoung, gcCause, duration); break; - case MAJOR: - gcType = GarbageCollectionTypes.ZGCMajor; + case MAJOR_YOUNG: + cycle = new ZGCYoungCollection(startTimeStamp, GarbageCollectionTypes.ZGCMajorYoung, gcCause, duration); break; + case MAJOR_OLD: + cycle = new ZGCOldCollection(startTimeStamp, GarbageCollectionTypes.ZGCMajorOld, gcCause, duration); + break; + default: + throw new RuntimeException("Unknown GC phase: " + phase); } - // Duration recorded by GC - FullZGCCycle fullZGCCycle; - ZGCCycle delegate = getZGCCycle(endTime); - if (gcDuration != null){ - fullZGCCycle = new FullZGCCycle(startTimeStamp, gcType, gcCause, gcDuration, delegate); - } else { - fullZGCCycle = new FullZGCCycle(startTimeStamp, gcType, gcCause, endTime.minus(startTimeStamp), delegate); - } - - return fullZGCCycle; - } - - public ZGCCycle getZGCCycle(DateTimeStamp endTime) { - ZGCCycle cycle = new ZGCCycle(); cycle.setGcId(gcId); cycle.setType(type); cycle.setPhase(phase); @@ -835,7 +746,7 @@ public ZGCCycle getZGCCycle(DateTimeStamp endTime) { cycle.setConcurrentRemapRoots(concurrentRemapRootsStart, concurrentRemapRootsDuration); cycle.setPromotedSummary(promotedSummary); cycle.setCompactedSummary(compactedSummary); - cycle.setusedOccupancySummary(usedOccupancySummary); + cycle.setGenerationUsedSummary(generationUsedSummary); cycle.setSoftRefSummary(softRefSummary); cycle.setWeakRefSummary(weakRefSummary); cycle.setFinalRefSummary(finalRefSummary); @@ -1067,7 +978,7 @@ public void setGcDuration(double gcDuration) { this.gcDuration = gcDuration; } - public void setUsed(ZGCPhase phase, OccupancySummary summary) { + public void setGenerationUsedSummary(ZGCPhase phase, OccupancySummary summary) { switch (phase) { case FULL: // does not apply to non generational GC @@ -1075,7 +986,7 @@ public void setUsed(ZGCPhase phase, OccupancySummary summary) { case MAJOR_YOUNG: case MAJOR_OLD: case MINOR_YOUNG: - this.usedOccupancySummary = summary; + this.generationUsedSummary = summary; break; } } diff --git a/parser/src/main/java/com/microsoft/gctoolkit/parser/jvm/UnifiedDiarizer.java b/parser/src/main/java/com/microsoft/gctoolkit/parser/jvm/UnifiedDiarizer.java index 094292bb..30743a07 100644 --- a/parser/src/main/java/com/microsoft/gctoolkit/parser/jvm/UnifiedDiarizer.java +++ b/parser/src/main/java/com/microsoft/gctoolkit/parser/jvm/UnifiedDiarizer.java @@ -173,21 +173,26 @@ private void extractTagsAndLevels(Decorators decorators) { */ private void discoverCollector(String line) { - if ( ZGC_TAG.parse(line) != null || CYCLE_START.parse(line) != null) { + if (CYCLE_START.parse(line) != null) { + String cycleType = CYCLE_START.parse(line).getGroup(2); diary.setTrue(ZGC); - diary.setFalse(DEFNEW, SERIAL, PARALLELGC, PARALLELOLDGC, PARNEW, CMS, ICMS, G1GC, RSET_STATS, SHENANDOAH, CMS_DEBUG_LEVEL_1, PRE_JDK70_40, JDK70, JDK80, TENURING_DISTRIBUTION, MAX_TENURING_THRESHOLD_VIOLATION, TLAB_DATA, PRINT_PROMOTION_FAILURE, PRINT_FLS_STATISTICS); + if(cycleType.equals("Minor") || cycleType.equals("Major")) + diary.setTrue(GENERATIONAL_ZGC); + else + diary.setFalse(GENERATIONAL_ZGC); + diary.setFalse(DEFNEW, SERIAL, PARALLELGC, PARALLELOLDGC, PARNEW, CMS, ICMS, G1GC, RSET_STATS, SHENANDOAH, CMS_DEBUG_LEVEL_1, PRE_JDK70_40, JDK70, JDK80, TENURING_DISTRIBUTION, MAX_TENURING_THRESHOLD_VIOLATION, TLAB_DATA, PRINT_PROMOTION_FAILURE, PRINT_FLS_STATISTICS, ADAPTIVE_SIZING); return; } if ( SHENANDOAH_TAG.parse(line) != null) { diary.setTrue(SHENANDOAH); - diary.setFalse(DEFNEW, SERIAL, PARALLELGC, PARALLELOLDGC, PARNEW, CMS, ICMS, G1GC, RSET_STATS, ZGC, CMS_DEBUG_LEVEL_1, PRE_JDK70_40, JDK70, JDK80, TENURING_DISTRIBUTION, MAX_TENURING_THRESHOLD_VIOLATION, TLAB_DATA, PRINT_PROMOTION_FAILURE, PRINT_FLS_STATISTICS, PRINT_HEAP_AT_GC); + diary.setFalse(DEFNEW, SERIAL, PARALLELGC, PARALLELOLDGC, PARNEW, CMS, ICMS, G1GC, RSET_STATS, ZGC, CMS_DEBUG_LEVEL_1, PRE_JDK70_40, JDK70, JDK80, TENURING_DISTRIBUTION, MAX_TENURING_THRESHOLD_VIOLATION, TLAB_DATA, PRINT_PROMOTION_FAILURE, PRINT_FLS_STATISTICS, PRINT_HEAP_AT_GC, GENERATIONAL_ZGC); return; } if (G1_TAG.parse(line) != null || line.contains("G1 Evacuation Pause") || (line.contains("Humongous regions: "))) { diary.setTrue(G1GC); - diary.setFalse(DEFNEW, SERIAL, PARALLELGC, PARALLELOLDGC, PARNEW, CMS, ICMS, ZGC, SHENANDOAH, CMS_DEBUG_LEVEL_1, PRE_JDK70_40, JDK70, JDK80, TLAB_DATA, PRINT_PROMOTION_FAILURE, PRINT_FLS_STATISTICS); + diary.setFalse(DEFNEW, SERIAL, PARALLELGC, PARALLELOLDGC, PARNEW, CMS, ICMS, ZGC, SHENANDOAH, CMS_DEBUG_LEVEL_1, PRE_JDK70_40, JDK70, JDK80, TLAB_DATA, PRINT_PROMOTION_FAILURE, PRINT_FLS_STATISTICS, GENERATIONAL_ZGC); return; } @@ -195,7 +200,7 @@ private void discoverCollector(String line) { PARNEW_TAG.parse(line) != null || line.contains("ParNew")) { diary.setTrue(PARNEW, CMS); - diary.setFalse(DEFNEW, SERIAL, PARALLELGC, PARALLELOLDGC, ICMS, CMS_DEBUG_LEVEL_1, G1GC, ZGC, SHENANDOAH, PRE_JDK70_40, JDK70, JDK80, RSET_STATS); + diary.setFalse(DEFNEW, SERIAL, PARALLELGC, PARALLELOLDGC, ICMS, CMS_DEBUG_LEVEL_1, G1GC, ZGC, SHENANDOAH, PRE_JDK70_40, JDK70, JDK80, RSET_STATS, GENERATIONAL_ZGC); return; } @@ -203,13 +208,13 @@ private void discoverCollector(String line) { line.contains("ParOldGen") || line.contains("PSYoungGen")) { diary.setTrue(PARALLELGC, PARALLELOLDGC, GC_CAUSE); - diary.setFalse(DEFNEW, SERIAL, PARNEW, CMS, ICMS, CMS_DEBUG_LEVEL_1, G1GC, ZGC, SHENANDOAH, PRE_JDK70_40, JDK70, JDK80, RSET_STATS); + diary.setFalse(DEFNEW, SERIAL, PARNEW, CMS, ICMS, CMS_DEBUG_LEVEL_1, G1GC, ZGC, SHENANDOAH, PRE_JDK70_40, JDK70, JDK80, RSET_STATS, GENERATIONAL_ZGC); return; } if (SERIAL_TAG.parse(line) != null || line.contains("DefNew")) { diary.setTrue(DEFNEW, SERIAL, GC_CAUSE); - diary.setFalse(PARALLELGC, PARALLELOLDGC, PARNEW, CMS, ICMS, CMS_DEBUG_LEVEL_1, G1GC, ZGC, SHENANDOAH, PRE_JDK70_40, JDK70, JDK80, RSET_STATS); + diary.setFalse(PARALLELGC, PARALLELOLDGC, PARNEW, CMS, ICMS, CMS_DEBUG_LEVEL_1, G1GC, ZGC, SHENANDOAH, PRE_JDK70_40, JDK70, JDK80, RSET_STATS, GENERATIONAL_ZGC); return; } } 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 0688540e..a744aa64 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 @@ -20,6 +20,12 @@ public interface ZGCPatterns extends UnifiedPatterns { //[3.558s][info ][gc,start ] GC(3) Garbage Collection (Warmup) GCParseRule CYCLE_START = new GCParseRule("CYCLE_START", "GC\\(" + GenericTokens.INT + "\\) (Garbage|Major|Minor) Collection " + GenericTokens.GC_CAUSE + "$"); + // [2024-11-19T09:48:57.431-0600][info ][gc,phases ] GC(6) Y: Young Generation (Promote All) + // [2024-11-19T09:48:42.508-0600][info ][gc,phases ] GC(3) Y: Young Generation + // [2024-11-19T09:48:31.984-0600][info][gc,phases ] GC(0) O: Old Generation + // [2024-11-19T09:48:52.855-0600][info ][gc,phases ] GC(5) y: Young Generation + GCParseRule GENERATION_START = new GCParseRule("Generation Start", "GC\\(" + GenericTokens.INT + "\\) " + OPT_GEN + "(Young|Old) Generation(?: \\([a-zA-Z ]+\\))?$"); + //[3.559s][info ][gc,phases ] GC(3) Pause Mark Start 0.460ms //[3.574s][info ][gc,phases ] GC(3) Pause Mark End 0.830ms //[3.583s][info ][gc,phases ] GC(3) Pause Relocate Start 0.794ms @@ -101,11 +107,8 @@ public interface ZGCPatterns extends UnifiedPatterns { // Gen ZGC // [info][gc,heap ] GC(2) O: Old Generation Statistics: - GCParseRule MARK_OLD_GEN_HEAP_STATS = new GCParseRule("Mark Old Gen Stats", OPT_GEN + "Old Generation Statistics"); - - // Gen ZGC // [info][gc,heap ] GC(4) Y: Young Generation Statistics: - GCParseRule MARK_YOUNG_GEN_HEAP_STATS = new GCParseRule("Mark Young Gen Stats", OPT_GEN + "Young Generation Statistics"); + GCParseRule MARK_GEN_HEAP_STATS = new GCParseRule("Mark Gen Stats", OPT_GEN + "(Old|Young) Generation Statistics"); //[3.596s][info ][gc,heap ] GC(3) Live: - 8M (0%) 8M (0%) 8M (0%) - - //[3.596s][info ][gc,heap ] GC(3) Allocated: - 172M (4%) 172M (4%) 376M (9%) - - @@ -122,14 +125,15 @@ public interface ZGCPatterns extends UnifiedPatterns { // [info][gc,phases ] GC(58) Y: Young Generation 16052M(44%)->3022M(8%) 1.017s // [info][gc,phases ] GC(58) O: Old Generation 3022M(8%)->5486M(15%) 1.757s - GCParseRule END_OF_PHASE_SUMMARY_GEN = new GCParseRule("End of Phase Summary", OPT_GEN + "(Old|Young) Generation " + MEMORY_PERCENT + "->" + MEMORY_PERCENT + "\\s*" + PAUSE_TIME); + // [2024-11-19T09:49:02.950-0600][info ][gc,phases ] GC(6) Y: Young Generation (Promote All) 13184M(80%)->16384M(100%) 5.519s + GCParseRule END_OF_PHASE_SUMMARY_GEN = new GCParseRule("End of Phase Summary", OPT_GEN + "(Old|Young) Generation(?: \\([a-zA-Z ]+\\))? " + MEMORY_PERCENT + "->" + MEMORY_PERCENT + "\\s*" + PAUSE_TIME); //[3.596s][info ][gc ] GC(3) Garbage Collection (Warmup) 894M(22%)->186M(5%) // or // Gen GC //[3.596s][info][gc ] GC(7) Minor Collection (Allocation Rate) 14720M(40%)->2054M(6%) 0.689s - GCParseRule MEMORY_SUMMARY = new GCParseRule("Memory Summary", "(Garbage|Minor|Major) Collection " + GenericTokens.GC_CAUSE + MEMORY_PERCENT + "->" + MEMORY_PERCENT + "(?:\\s*" + PAUSE_TIME + ")?"); + GCParseRule MEMORY_SUMMARY = new GCParseRule("Memory Summary", "GC\\("+ GenericTokens.INT + "\\)\\s*(Garbage|Minor|Major) Collection " + GenericTokens.GC_CAUSE + MEMORY_PERCENT + "->" + MEMORY_PERCENT + "(?:\\s*" + PAUSE_TIME + ")?"); /* todo: capture and report on these log entries 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 99efe2e9..1cd36d8d 100644 --- a/parser/src/test/java/com/microsoft/gctoolkit/parser/GenerationalZGCParserTest.java +++ b/parser/src/test/java/com/microsoft/gctoolkit/parser/GenerationalZGCParserTest.java @@ -2,24 +2,9 @@ // Licensed under the MIT License. package com.microsoft.gctoolkit.parser; +import com.microsoft.gctoolkit.event.GarbageCollectionTypes; import com.microsoft.gctoolkit.event.jvm.JVMEvent; -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; +import com.microsoft.gctoolkit.event.zgc.*; import com.microsoft.gctoolkit.jvm.Diarizer; import com.microsoft.gctoolkit.parser.jvm.UnifiedDiarizer; import com.microsoft.gctoolkit.time.DateTimeStamp; @@ -138,21 +123,20 @@ public void testZgcMajorCycle() { }; - List singleCycle = feedParser(eventLogEntries); + List singleYoungSingleOld = feedParser(eventLogEntries); try { - assertEquals(1, singleCycle.size()); - MajorZGCCycle zgc = (MajorZGCCycle) singleCycle.get(0); + assertEquals(2, singleYoungSingleOld.size()); - assertEquals(zgc.getGcId(), 1L); + ZGCYoungCollection young = (ZGCYoungCollection) singleYoungSingleOld.get(0); - assertEquals(toInt(0.1039d,1000), toInt(zgc.getDuration(),1000)); - assertEquals(toInt(1.739307979476E9, 1000), toInt(zgc.getDateTimeStamp().getTimeStamp(), 1000)); - assertEquals("Metadata GC Threshold", zgc.getGCCause().getLabel()); + assertEquals(young.getGcId(), 1L); + assertEquals(toInt(0.075d, 1000), toInt(young.getDuration(),1000)); + assertEquals(toInt(1.739307979476E9, 1000), toInt(young.getDateTimeStamp().getTimeStamp(), 1000)); + assertEquals("Metadata GC Threshold", young.getGCCause().getLabel()); /* * Young Phase Checks */ - ZGCCycle young = zgc.getYoungCycle(); // Durations assertTrue(checkDateTimeStampMatch("2025-02-11T13:06:19.476-0800", 0.023, young.getPauseMarkStartTimeStamp())); assertTrue(checkDateTimeStampMatch("2025-02-11T13:06:19.534-0800", 57.581, young.getConcurrentMarkTimeStamp())); @@ -182,7 +166,7 @@ public void testZgcMajorCycle() { assertTrue(checkZGCMetaSpaceSummary(young.getMetaspaceSummary(),36, 37, 1088)); - assertTrue(checkUsedSummary(young.getUsedOccupancySummary(), 296, 308, 240, 76)); + assertTrue(checkUsedSummary(young.getGenerationUsedSummary(), 296, 308, 240, 76)); assertTrue(checkLiveSummary(young.getLiveSummary(), 24, 24, 24)); assertTrue(checkGarbageSummary(young.getGarbageSummary(), 271, 203, 31)); assertTrue(checkAllocatedSummary(young.getAllocatedSummary(), 12, 12, 19)); @@ -220,7 +204,13 @@ public void testZgcMajorCycle() { /* * Old Phase Checks */ - ZGCCycle old = zgc.getOldCycle(); + ZGCOldCollection old = (ZGCOldCollection) singleYoungSingleOld.get(1); + + assertEquals(old.getGcId(), 1L); + assertEquals(toInt(0.029d, 1000), toInt(old.getDuration(),1000)); + assertEquals(toInt(1.739307979476E9, 1000), toInt(old.getDateTimeStamp().getTimeStamp(), 1000)); + assertEquals("Metadata GC Threshold", old.getGCCause().getLabel()); + // Durations assertTrue(checkDateTimeStampMatch("2025-02-11T13:06:19.553-0800", 1.286, old.getConcurrentMarkTimeStamp())); assertTrue(checkDateTimeStampMatch("2025-02-11T13:06:19.553-0800", 0.017, old.getPauseMarkEndTimeStamp())); @@ -263,7 +253,7 @@ public void testZgcMajorCycle() { assertEquals(125 * 1024, old.getForwardingUsage()); - assertTrue(checkUsedSummary(old.getUsedOccupancySummary(), 0, 0, 0, 0)); + assertTrue(checkUsedSummary(old.getGenerationUsedSummary(), 0, 0, 0, 0)); assertTrue(checkLiveSummary(old.getLiveSummary(), 0, 0, 0)); assertTrue(checkGarbageSummary(old.getGarbageSummary(), 0, 0, 0)); assertTrue(checkAllocatedSummary(old.getAllocatedSummary(), 0, 0, 0)); @@ -348,18 +338,14 @@ public void testZgcMinorCycle() { List singleCycle = feedParser(eventLogEntries); try { assertEquals(1, singleCycle.size()); - MinorZGCCycle zgc = (MinorZGCCycle) singleCycle.get(0); + ZGCYoungCollection young = (ZGCYoungCollection) singleCycle.get(0); - assertEquals(zgc.getGcId(), 7L); + assertEquals(young.getGcId(), 7L); - assertEquals(toInt(0.690d,1000), toInt(zgc.getDuration(),1000)); - assertTrue(checkDateTimeStampMatch("2025-02-11T13:07:12.566-0800", 0, zgc.getDateTimeStamp())); - assertEquals("Allocation Rate", zgc.getGCCause().getLabel()); + assertEquals(toInt(0.689d,1000), toInt(young.getDuration(),1000)); + assertTrue(checkDateTimeStampMatch("2025-02-11T13:07:12.566-0800", 0, young.getDateTimeStamp())); + assertEquals("Allocation Rate", young.getGCCause().getLabel()); - /* - * Young Phase Checks - */ - ZGCCycle young = zgc.getYoungCycle(); // Durations assertTrue(checkDateTimeStampMatch("2025-02-11T13:07:12.566-0800", 0.025, young.getPauseMarkStartTimeStamp())); assertTrue(checkDateTimeStampMatch("2025-02-11T13:07:13.042-0800", 475.464, young.getConcurrentMarkTimeStamp())); @@ -389,7 +375,7 @@ public void testZgcMinorCycle() { assertTrue(checkZGCMetaSpaceSummary(young.getMetaspaceSummary(),100, 101, 1152)); - assertTrue(checkUsedSummary(young.getUsedOccupancySummary(), 14132, 14900, 12364, 1466)); + assertTrue(checkUsedSummary(young.getGenerationUsedSummary(), 14132, 14900, 12364, 1466)); assertTrue(checkLiveSummary(young.getLiveSummary(), 120, 120, 120)); assertTrue(checkGarbageSummary(young.getGarbageSummary(), 14011, 11457, 2)); assertTrue(checkAllocatedSummary(young.getAllocatedSummary(), 768, 786, 1343)); @@ -429,6 +415,225 @@ public void testZgcMinorCycle() { } } + @Test + public void testMultipleConcurrentCycles() { + String[] eventLogEntries = { + "[2024-11-19T09:48:42.508-0600][info ][gc ] GC(3) Major Collection (Warmup)", + "[2024-11-19T09:48:42.508-0600][info ][gc,task ] GC(3) Using 3 Workers for Young Generation", + "[2024-11-19T09:48:42.508-0600][info ][gc,task ] GC(3) Using 1 Workers for Old Generation", + "[2024-11-19T09:48:42.508-0600][info ][gc,phases ] GC(3) Y: Young Generation", + "[2024-11-19T09:48:42.509-0600][info ][gc,phases ] GC(3) Y: Pause Mark Start (Major) 0.005ms", + "[2024-11-19T09:48:45.908-0600][info ][gc,phases ] GC(3) Y: Concurrent Mark 3399.497ms", + "[2024-11-19T09:48:45.908-0600][info ][gc,phases ] GC(3) Y: Pause Mark End 0.016ms", + "[2024-11-19T09:48:45.908-0600][info ][gc,phases ] GC(3) Y: Concurrent Mark Free 0.000ms", + "[2024-11-19T09:48:45.908-0600][info ][gc,phases ] GC(3) Y: Concurrent Reset Relocation Set 0.054ms", + "[2024-11-19T09:48:45.910-0600][info ][gc,reloc ] GC(3) Y: Using tenuring threshold: 4 (Computed)", + "[2024-11-19T09:48:46.044-0600][info ][gc,phases ] GC(3) Y: Concurrent Select Relocation Set 135.227ms", + "[2024-11-19T09:48:46.045-0600][info ][gc,phases ] GC(3) Y: Pause Relocate Start 0.024ms", + "[2024-11-19T09:48:47.878-0600][info ][gc,phases ] GC(3) Y: Concurrent Relocate 1829.530ms", + "[2024-11-19T09:48:47.878-0600][info ][gc,alloc ] GC(3) Y: Mark Start Mark End Relocate Start Relocate End", + "[2024-11-19T09:48:47.878-0600][info ][gc,alloc ] GC(3) Y: Allocation Stalls: 0 38 0 0", + "[2024-11-19T09:48:47.879-0600][info ][gc,load ] GC(3) Y: Load: 22.08 (184%) / 8.18 (68%) / 4.99 (42%)", + "[2024-11-19T09:48:47.879-0600][info ][gc,mmu ] GC(3) Y: MMU: 2ms/98.8%, 5ms/99.5%, 10ms/99.8%, 20ms/99.9%, 50ms/99.9%, 100ms/100.0%", + "[2024-11-19T09:48:47.879-0600][info ][gc,marking ] GC(3) Y: Mark: 2 stripe(s), 10 proactive flush(es), 1 terminate flush(es), 0 completion(s), 0 continuation(s)", + "[2024-11-19T09:48:47.879-0600][info ][gc,marking ] GC(3) Y: Mark Stack Usage: 32M", + "[2024-11-19T09:48:47.879-0600][info ][gc,nmethod ] GC(3) Y: NMethods: 5348 registered, 0 unregistered", + "[2024-11-19T09:48:47.879-0600][info ][gc,metaspace] GC(3) Y: Metaspace: 45M used, 46M committed, 1088M reserved", + "[2024-11-19T09:48:47.879-0600][info ][gc,reloc ] GC(3) Y: Candidates Selected In-Place Size Empty Relocated", + "[2024-11-19T09:48:47.879-0600][info ][gc,reloc ] GC(3) Y: Small Pages: 4449 2921 0 8898M 664M 1107M", + "[2024-11-19T09:48:47.879-0600][info ][gc,reloc ] GC(3) Y: Medium Pages: 2 1 0 64M 0M 0M", + "[2024-11-19T09:48:47.879-0600][info ][gc,reloc ] GC(3) Y: Large Pages: 0 0 0 0M 0M 0M", + "[2024-11-19T09:48:47.879-0600][info ][gc,reloc ] GC(3) Y: Forwarding Usage: 600M", + "[2024-11-19T09:48:47.879-0600][info ][gc,reloc ] GC(3) Y: Age Table:", + "[2024-11-19T09:48:47.879-0600][info ][gc,reloc ] GC(3) Y: Live Garbage Small Medium Large", + "[2024-11-19T09:48:47.879-0600][info ][gc,reloc ] GC(3) Y: Eden 1710M (10%) 6677M (41%) 4194 / 2878 0 / 0 0 / 0", + "[2024-11-19T09:48:47.879-0600][info ][gc,reloc ] GC(3) Y: Survivor 1 266M (2%) 137M (1%) 202 / 39 0 / 0 0 / 0", + "[2024-11-19T09:48:47.879-0600][info ][gc,reloc ] GC(3) Y: Survivor 2 77M (0%) 44M (0%) 45 / 3 1 / 1 0 / 0", + "[2024-11-19T09:48:47.883-0600][info ][gc,reloc ] GC(3) Y: Survivor 3 12M (0%) 35M (0%) 8 / 1 1 / 0 0 / 0", + "[2024-11-19T09:48:47.883-0600][info ][gc,heap ] GC(3) Y: Min Capacity: 8M(0%)", + "[2024-11-19T09:48:47.883-0600][info ][gc,heap ] GC(3) Y: Max Capacity: 16384M(100%)", + "[2024-11-19T09:48:47.883-0600][info ][gc,heap ] GC(3) Y: Soft Max Capacity: 16384M(100%)", + "[2024-11-19T09:48:47.883-0600][info ][gc,heap ] GC(3) Y: Heap Statistics:", + "[2024-11-19T09:48:47.883-0600][info ][gc,heap ] GC(3) Y: Mark Start Mark End Relocate Start Relocate End High Low", + "[2024-11-19T09:48:47.883-0600][info ][gc,heap ] GC(3) Y: Capacity: 8962M (55%) 16384M (100%) 16384M (100%) 16384M (100%) 16384M (100%) 8962M (55%)", + "[2024-11-19T09:48:47.883-0600][info ][gc,heap ] GC(3) Y: Free: 7422M (45%) 0M (0%) 468M (3%) 3080M (19%) 7422M (45%) 0M (0%)", + "[2024-11-19T09:48:47.883-0600][info ][gc,heap ] GC(3) Y: Used: 8962M (55%) 16384M (100%) 15916M (97%) 13304M (81%) 16384M (100%) 8962M (55%)", + "[2024-11-19T09:48:47.883-0600][info ][gc,heap ] GC(3) Y: Young Generation Statistics:", + "[2024-11-19T09:48:47.883-0600][info ][gc,heap ] GC(3) Y: Mark Start Mark End Relocate Start Relocate End", + "[2024-11-19T09:48:47.883-0600][info ][gc,heap ] GC(3) Y: Used: 8962M (55%) 16384M (100%) 15916M (97%) 13304M (81%)", + "[2024-11-19T09:48:47.883-0600][info ][gc,heap ] GC(3) Y: Live: - 2067M (13%) 2067M (13%) 2067M (13%)", + "[2024-11-19T09:48:47.883-0600][info ][gc,heap ] GC(3) Y: Garbage: - 6894M (42%) 6230M (38%) 53M (0%)", + "[2024-11-19T09:48:47.883-0600][info ][gc,heap ] GC(3) Y: Allocated: - 7422M (45%) 7618M (46%) 11183M (68%)", + "[2024-11-19T09:48:47.883-0600][info ][gc,heap ] GC(3) Y: Reclaimed: - - 664M (4%) 6841M (42%)", + "[2024-11-19T09:48:47.883-0600][info ][gc,heap ] GC(3) Y: Promoted: - - 0M (0%) 0M (0%)", + "[2024-11-19T09:48:47.883-0600][info ][gc,heap ] GC(3) Y: Compacted: - - - 1768M (11%)", + "[2024-11-19T09:48:47.883-0600][info ][gc,phases ] GC(3) Y: Young Generation 8962M(55%)->13304M(81%) 5.370s", + "[2024-11-19T09:48:47.883-0600][info ][gc,phases ] GC(3) O: Old Generation", + "[2024-11-19T09:48:47.883-0600][info ][gc ] GC(4) Minor Collection (Allocation Stall)", + "[2024-11-19T09:48:47.883-0600][info ][gc,task ] GC(4) Using 3 Workers for Young Generation", + "[2024-11-19T09:48:47.883-0600][info ][gc,phases ] GC(4) y: Young Generation", + "[2024-11-19T09:48:47.902-0600][info ][gc,phases ] GC(4) y: Pause Mark Start 0.009ms", + "[2024-11-19T09:48:48.014-0600][info ][gc,phases ] GC(3) O: Concurrent Mark 131.401ms", + "[2024-11-19T09:48:48.051-0600][info ][gc,phases ] GC(3) O: Pause Mark End 0.011ms", + "[2024-11-19T09:48:48.051-0600][info ][gc,phases ] GC(3) O: Concurrent Mark Free 0.001ms", + "[2024-11-19T09:48:48.088-0600][info ][gc,phases ] GC(3) O: Concurrent Process Non-Strong 37.017ms", + "[2024-11-19T09:48:48.088-0600][info ][gc,phases ] GC(3) O: Concurrent Reset Relocation Set 0.000ms", + "[2024-11-19T09:48:48.091-0600][info ][gc,phases ] GC(3) O: Concurrent Select Relocation Set 2.566ms", + "[2024-11-19T09:48:50.579-0600][info ][gc,phases ] GC(4) y: Concurrent Mark 2673.028ms", + "[2024-11-19T09:48:50.579-0600][info ][gc,phases ] GC(4) y: Pause Mark End 0.009ms", + "[2024-11-19T09:48:50.579-0600][info ][gc,phases ] GC(4) y: Concurrent Mark Free 0.000ms", + "[2024-11-19T09:48:50.579-0600][info ][gc,phases ] GC(4) y: Concurrent Reset Relocation Set 0.205ms", + "[2024-11-19T09:48:50.580-0600][info ][gc,reloc ] GC(4) y: Using tenuring threshold: 2 (Computed)", + "[2024-11-19T09:48:50.707-0600][info ][gc,phases ] GC(4) y: Concurrent Select Relocation Set 128.026ms", + "[2024-11-19T09:48:50.709-0600][info ][gc,phases ] GC(4) y: Pause Relocate Start 0.013ms", + "[2024-11-19T09:48:52.806-0600][info ][gc,phases ] GC(4) y: Concurrent Relocate 2096.795ms", + "[2024-11-19T09:48:52.809-0600][info ][gc,alloc ] GC(4) y: Mark Start Mark End Relocate Start Relocate End", + "[2024-11-19T09:48:52.809-0600][info ][gc,alloc ] GC(4) y: Allocation Stalls: 0 37 54 0", + "[2024-11-19T09:48:52.809-0600][info ][gc,load ] GC(4) y: Load: 24.64 (205%) / 8.94 (75%) / 5.27 (44%)", + "[2024-11-19T09:48:52.809-0600][info ][gc,mmu ] GC(4) y: MMU: 2ms/98.8%, 5ms/99.5%, 10ms/99.8%, 20ms/99.9%, 50ms/99.9%, 100ms/100.0%", + "[2024-11-19T09:48:52.809-0600][info ][gc,marking ] GC(4) y: Mark: 2 stripe(s), 10 proactive flush(es), 1 terminate flush(es), 0 completion(s), 0 continuation(s)", + "[2024-11-19T09:48:52.809-0600][info ][gc,marking ] GC(4) y: Mark Stack Usage: 32M", + "[2024-11-19T09:48:52.809-0600][info ][gc,nmethod ] GC(4) y: NMethods: 5329 registered, 373 unregistered", + "[2024-11-19T09:48:52.809-0600][info ][gc,metaspace] GC(4) y: Metaspace: 46M used, 46M committed, 1088M reserved", + "[2024-11-19T09:48:52.809-0600][info ][gc,reloc ] GC(4) y: Candidates Selected In-Place Size Empty Relocated", + "[2024-11-19T09:48:52.809-0600][info ][gc,reloc ] GC(4) y: Small Pages: 6654 4106 13 13308M 402M 1531M", + "[2024-11-19T09:48:52.809-0600][info ][gc,reloc ] GC(4) y: Medium Pages: 2 1 1 64M 0M 0M", + "[2024-11-19T09:48:52.809-0600][info ][gc,reloc ] GC(4) y: Large Pages: 0 0 0 0M 0M 0M", + "[2024-11-19T09:48:52.809-0600][info ][gc,reloc ] GC(4) y: Forwarding Usage: 841M", + "[2024-11-19T09:48:52.809-0600][info ][gc,reloc ] GC(4) y: Age Table:", + "[2024-11-19T09:48:52.809-0600][info ][gc,reloc ] GC(4) y: Live Garbage Small Medium Large", + "[2024-11-19T09:48:52.809-0600][info ][gc,reloc ] GC(4) y: Eden 2373M (14%) 8800M (54%) 5587 / 4007 0 / 0 0 / 0", + "[2024-11-19T09:48:52.809-0600][info ][gc,reloc ] GC(4) y: Survivor 1 1635M (10%) 84M (1%) 860 / 7 0 / 0 0 / 0", + "[2024-11-19T09:48:52.809-0600][info ][gc,reloc ] GC(4) y: Survivor 2 113M (1%) 194M (1%) 154 / 87 0 / 0 0 / 0", + "[2024-11-19T09:48:52.809-0600][info ][gc,reloc ] GC(4) y: Survivor 3 76M (0%) 45M (0%) 45 / 3 1 / 1 0 / 0", + "[2024-11-19T09:48:52.809-0600][info ][gc,reloc ] GC(4) y: Survivor 4 12M (0%) 35M (0%) 8 / 2 1 / 0 0 / 0", + "[2024-11-19T09:48:52.809-0600][info ][gc,heap ] GC(4) y: Min Capacity: 8M(0%)", + "[2024-11-19T09:48:52.809-0600][info ][gc,heap ] GC(4) y: Max Capacity: 16384M(100%)", + "[2024-11-19T09:48:52.813-0600][info ][gc,heap ] GC(4) y: Soft Max Capacity: 16384M(100%)", + "[2024-11-19T09:48:52.813-0600][info ][gc,heap ] GC(4) y: Heap Statistics:", + "[2024-11-19T09:48:52.813-0600][info ][gc,heap ] GC(4) y: Mark Start Mark End Relocate Start Relocate End High Low", + "[2024-11-19T09:48:52.813-0600][info ][gc,heap ] GC(4) y: Capacity: 16384M (100%) 16384M (100%) 16384M (100%) 16384M (100%) 16384M (100%) 16384M (100%)", + "[2024-11-19T09:48:52.817-0600][info ][gc,heap ] GC(4) y: Free: 3012M (18%) 0M (0%) 0M (0%) 730M (4%) 4170M (25%) 0M (0%)", + "[2024-11-19T09:48:52.817-0600][info ][gc,heap ] GC(4) y: Used: 13372M (82%) 16384M (100%) 16384M (100%) 15654M (96%) 16384M (100%) 12214M (75%)", + "[2024-11-19T09:48:52.817-0600][info ][gc,heap ] GC(4) y: Young Generation Statistics:", + "[2024-11-19T09:48:52.817-0600][info ][gc,heap ] GC(4) y: Mark Start Mark End Relocate Start Relocate End", + "[2024-11-19T09:48:52.821-0600][info ][gc,heap ] GC(4) y: Used: 13372M (82%) 16384M (100%) 16260M (99%) 15400M (94%)", + "[2024-11-19T09:48:52.821-0600][info ][gc,heap ] GC(4) y: Live: - 4210M (26%) 4105M (25%) 4009M (24%)", + "[2024-11-19T09:48:52.821-0600][info ][gc,heap ] GC(4) y: Garbage: - 9161M (56%) 8740M (53%) 87M (1%)", + "[2024-11-19T09:48:52.821-0600][info ][gc,heap ] GC(4) y: Allocated: - 3012M (18%) 3414M (21%) 11303M (69%)", + "[2024-11-19T09:48:52.821-0600][info ][gc,heap ] GC(4) y: Reclaimed: - - 420M (3%) 9073M (55%)", + "[2024-11-19T09:48:52.821-0600][info ][gc,heap ] GC(4) y: Promoted: - - 105M (1%) 201M (1%)", + "[2024-11-19T09:48:52.821-0600][info ][gc,heap ] GC(4) y: Compacted: - - - 2352M (14%)", + "[2024-11-19T09:48:52.821-0600][info ][gc,phases ] GC(4) y: Young Generation 13310M(81%)->15654M(96%) 4.926s", + "[2024-11-19T09:48:52.821-0600][info ][gc ] GC(4) Minor Collection (Allocation Stall) 13310M(81%)->15734M(96%) 4.938s", + "[2024-11-19T09:48:52.821-0600][info ][gc,task ] GC(3) O: Using 3 Workers for Old Generation", + "[2024-11-19T09:48:52.853-0600][info ][gc,task ] GC(3) O: Using 1 Workers for Old Generation", + "[2024-11-19T09:48:52.855-0600][info ][gc,phases ] GC(3) O: Concurrent Remap Roots 33.641ms", + "[2024-11-19T09:48:52.855-0600][info ][gc,phases ] GC(3) O: Pause Relocate Start 0.006ms", + "[2024-11-19T09:48:52.855-0600][info ][gc ] GC(5) Minor Collection (Allocation Rate)", + "[2024-11-19T09:48:52.855-0600][info ][gc,task ] GC(5) Using 3 Workers for Young Generation", + "[2024-11-19T09:48:52.855-0600][info ][gc,phases ] GC(5) y: Young Generation", + "[2024-11-19T09:48:52.860-0600][info ][gc,phases ] GC(5) y: Pause Mark Start 0.004ms", + "[2024-11-19T09:48:52.868-0600][info ][gc,phases ] GC(3) O: Concurrent Relocate 12.604ms", + "[2024-11-19T09:48:55.559-0600][info ][gc,phases ] GC(5) y: Concurrent Mark 2695.516ms", + "[2024-11-19T09:48:55.559-0600][info ][gc,phases ] GC(5) y: Pause Mark End 0.013ms", + "[2024-11-19T09:48:55.559-0600][info ][gc,phases ] GC(5) y: Concurrent Mark Free 0.000ms", + "[2024-11-19T09:48:55.559-0600][info ][gc,phases ] GC(5) y: Concurrent Reset Relocation Set 0.377ms", + "[2024-11-19T09:48:55.561-0600][info ][gc,reloc ] GC(5) y: Using tenuring threshold: 2 (Computed)", + "[2024-11-19T09:48:55.828-0600][info ][gc,phases ] GC(5) y: Concurrent Select Relocation Set 268.261ms", + "[2024-11-19T09:48:55.830-0600][info ][gc,phases ] GC(5) y: Pause Relocate Start 0.005ms", + "[2024-11-19T09:48:57.412-0600][info ][gc,phases ] GC(5) y: Concurrent Relocate 1581.464ms", + "[2024-11-19T09:48:57.415-0600][info ][gc,alloc ] GC(5) y: Mark Start Mark End Relocate Start Relocate End", + "[2024-11-19T09:48:57.415-0600][info ][gc,alloc ] GC(5) y: Allocation Stalls: 0 65 33 0", + "[2024-11-19T09:48:57.415-0600][info ][gc,load ] GC(5) y: Load: 25.07 (209%) / 9.29 (77%) / 5.42 (45%)", + "[2024-11-19T09:48:57.415-0600][info ][gc,mmu ] GC(5) y: MMU: 2ms/98.8%, 5ms/99.5%, 10ms/99.8%, 20ms/99.9%, 50ms/99.9%, 100ms/100.0%", + "[2024-11-19T09:48:57.415-0600][info ][gc,marking ] GC(5) y: Mark: 2 stripe(s), 10 proactive flush(es), 1 terminate flush(es), 0 completion(s), 0 continuation(s)", + "[2024-11-19T09:48:57.415-0600][info ][gc,marking ] GC(5) y: Mark Stack Usage: 32M", + "[2024-11-19T09:48:57.415-0600][info ][gc,nmethod ] GC(5) y: NMethods: 5407 registered, 0 unregistered", + "[2024-11-19T09:48:57.415-0600][info ][gc,metaspace] GC(5) y: Metaspace: 46M used, 46M committed, 1088M reserved", + "[2024-11-19T09:48:57.415-0600][info ][gc,reloc ] GC(5) y: Candidates Selected In-Place Size Empty Relocated", + "[2024-11-19T09:48:57.415-0600][info ][gc,reloc ] GC(5) y: Small Pages: 7818 4111 2 15636M 1020M 1285M", + "[2024-11-19T09:48:57.415-0600][info ][gc,reloc ] GC(5) y: Medium Pages: 0 0 0 0M 0M 0M", + "[2024-11-19T09:48:57.418-0600][info ][gc,reloc ] GC(5) y: Large Pages: 0 0 0 0M 0M 0M", + "[2024-11-19T09:48:57.418-0600][info ][gc,reloc ] GC(5) y: Forwarding Usage: 705M", + "[2024-11-19T09:48:57.418-0600][info ][gc,reloc ] GC(5) y: Age Table:", + "[2024-11-19T09:48:57.418-0600][info ][gc,reloc ] GC(5) y: Live Garbage Small Medium Large", + "[2024-11-19T09:48:57.418-0600][info ][gc,reloc ] GC(5) y: Eden 2017M (12%) 9514M (58%) 5766 / 4091 0 / 0 0 / 0", + "[2024-11-19T09:48:57.418-0600][info ][gc,reloc ] GC(5) y: Survivor 1 2356M (14%) 39M (0%) 1198 / 2 0 / 0 0 / 0", + "[2024-11-19T09:48:57.418-0600][info ][gc,reloc ] GC(5) y: Survivor 2 1477M (9%) 230M (1%) 854 / 18 0 / 0 0 / 0", + "[2024-11-19T09:48:57.418-0600][info ][gc,heap ] GC(5) y: Min Capacity: 8M(0%)", + "[2024-11-19T09:48:57.418-0600][info ][gc,heap ] GC(5) y: Max Capacity: 16384M(100%)", + "[2024-11-19T09:48:57.418-0600][info ][gc,heap ] GC(5) y: Soft Max Capacity: 16384M(100%)", + "[2024-11-19T09:48:57.419-0600][info ][gc,heap ] GC(5) y: Heap Statistics:", + "[2024-11-19T09:48:57.419-0600][info ][gc,heap ] GC(5) y: Mark Start Mark End Relocate Start Relocate End High Low", + "[2024-11-19T09:48:57.419-0600][info ][gc,heap ] GC(5) y: Capacity: 16384M (100%) 16384M (100%) 16384M (100%) 16384M (100%) 16384M (100%) 16384M (100%)", + "[2024-11-19T09:48:57.419-0600][info ][gc,heap ] GC(5) y: Free: 494M (3%) 0M (0%) 0M (0%) 3288M (20%) 6336M (39%) 0M (0%)", + "[2024-11-19T09:48:57.419-0600][info ][gc,heap ] GC(5) y: Used: 15890M (97%) 16384M (100%) 16384M (100%) 13096M (80%) 16384M (100%) 10048M (61%)", + "[2024-11-19T09:48:57.422-0600][info ][gc,heap ] GC(5) y: Young Generation Statistics:", + "[2024-11-19T09:48:57.422-0600][info ][gc,heap ] GC(5) y: Mark Start Mark End Relocate Start Relocate End", + "[2024-11-19T09:48:57.422-0600][info ][gc,heap ] GC(5) y: Used: 15636M (95%) 16130M (98%) 14524M (89%) 11180M (68%)", + "[2024-11-19T09:48:57.422-0600][info ][gc,heap ] GC(5) y: Live: - 5852M (36%) 4426M (27%) 4374M (27%)", + "[2024-11-19T09:48:57.422-0600][info ][gc,heap ] GC(5) y: Garbage: - 9783M (60%) 8583M (52%) 47M (0%)", + "[2024-11-19T09:48:57.422-0600][info ][gc,heap ] GC(5) y: Allocated: - 494M (3%) 1514M (9%) 6758M (41%)", + "[2024-11-19T09:48:57.422-0600][info ][gc,heap ] GC(5) y: Reclaimed: - - 1200M (7%) 9736M (59%)", + "[2024-11-19T09:48:57.422-0600][info ][gc,heap ] GC(5) y: Promoted: - - 1425M (9%) 1477M (9%)", + "[2024-11-19T09:48:57.422-0600][info ][gc,heap ] GC(5) y: Compacted: - - - 1995M (12%)", + "[2024-11-19T09:48:57.422-0600][info ][gc,phases ] GC(5) y: Young Generation 15890M(97%)->13096M(80%) 4.560s", + "[2024-11-19T09:48:57.422-0600][info ][gc ] GC(5) Minor Collection (Allocation Rate) 15882M(97%)->13144M(80%) 4.567s", + "[2024-11-19T09:48:57.422-0600][info ][gc,alloc ] GC(3) O: Mark Start Mark End Relocate Start Relocate End", + "[2024-11-19T09:48:57.423-0600][info ][gc,alloc ] GC(3) O: Allocation Stalls: 0 0 0 0", + "[2024-11-19T09:48:57.423-0600][info ][gc,load ] GC(3) O: Load: 25.07 (209%) / 9.29 (77%) / 5.42 (45%)", + "[2024-11-19T09:48:57.427-0600][info ][gc,mmu ] GC(3) O: MMU: 2ms/98.8%, 5ms/99.5%, 10ms/99.8%, 20ms/99.9%, 50ms/99.9%, 100ms/100.0%", + "[2024-11-19T09:48:57.427-0600][info ][gc,marking ] GC(3) O: Mark: 1 stripe(s), 1 proactive flush(es), 1 terminate flush(es), 0 completion(s), 0 continuation(s)", + "[2024-11-19T09:48:57.427-0600][info ][gc,marking ] GC(3) O: Mark Stack Usage: 0M", + "[2024-11-19T09:48:57.427-0600][info ][gc,nmethod ] GC(3) O: NMethods: 5407 registered, 0 unregistered", + "[2024-11-19T09:48:57.427-0600][info ][gc,metaspace] GC(3) O: Metaspace: 46M used, 46M committed, 1088M reserved", + "[2024-11-19T09:48:57.427-0600][info ][gc,ref ] GC(3) O: Encountered Discovered Enqueued", + "[2024-11-19T09:48:57.427-0600][info ][gc,ref ] GC(3) O: Soft References: 4553 0 0", + "[2024-11-19T09:48:57.427-0600][info ][gc,ref ] GC(3) O: Weak References: 11144 0 0", + "[2024-11-19T09:48:57.427-0600][info ][gc,ref ] GC(3) O: Final References: 936 0 0", + "[2024-11-19T09:48:57.427-0600][info ][gc,ref ] GC(3) O: Phantom References: 8720 0 0", + "[2024-11-19T09:48:57.427-0600][info ][gc,heap ] GC(3) O: Min Capacity: 8M(0%)", + "[2024-11-19T09:48:57.427-0600][info ][gc,heap ] GC(3) O: Max Capacity: 16384M(100%)", + "[2024-11-19T09:48:57.427-0600][info ][gc,heap ] GC(3) O: Soft Max Capacity: 16384M(100%)", + "[2024-11-19T09:48:57.427-0600][info ][gc,heap ] GC(3) O: Heap Statistics:", + "[2024-11-19T09:48:57.427-0600][info ][gc,heap ] GC(3) O: Mark Start Mark End Relocate Start Relocate End High Low", + "[2024-11-19T09:48:57.427-0600][info ][gc,heap ] GC(3) O: Capacity: 8962M (55%) 16384M (100%) 16384M (100%) 16384M (100%) 16384M (100%) 8962M (55%)", + "[2024-11-19T09:48:57.431-0600][info ][gc,heap ] GC(3) O: Free: 7422M (45%) 2516M (15%) 502M (3%) 484M (3%) 7422M (45%) 0M (0%)", + "[2024-11-19T09:48:57.431-0600][info ][gc,heap ] GC(3) O: Used: 8962M (55%) 13868M (85%) 15882M (97%) 15900M (97%) 16384M (100%) 8962M (55%)", + "[2024-11-19T09:48:57.431-0600][info ][gc,heap ] GC(3) O: Old Generation Statistics:", + "[2024-11-19T09:48:57.431-0600][info ][gc,heap ] GC(3) O: Mark Start Mark End Relocate Start Relocate End", + "[2024-11-19T09:48:57.431-0600][info ][gc,heap ] GC(3) O: Used: 0M (0%) 0M (0%) 254M (2%) 254M (2%)", + "[2024-11-19T09:48:57.431-0600][info ][gc,heap ] GC(3) O: Live: - 0M (0%) 0M (0%) 0M (0%)", + "[2024-11-19T09:48:57.431-0600][info ][gc,heap ] GC(3) O: Garbage: - 0M (0%) 0M (0%) 0M (0%)", + "[2024-11-19T09:48:57.431-0600][info ][gc,heap ] GC(3) O: Allocated: - 0M (0%) 254M (2%) 254M (2%)", + "[2024-11-19T09:48:57.431-0600][info ][gc,heap ] GC(3) O: Reclaimed: - - 0M (0%) 0M (0%)", + "[2024-11-19T09:48:57.431-0600][info ][gc,heap ] GC(3) O: Compacted: - - - 0M (0%)", + "[2024-11-19T09:48:57.431-0600][info ][gc,phases ] GC(3) O: Old Generation 13310M(81%)->15900M(97%) 9.540s", + "[2024-11-19T09:48:57.431-0600][info ][gc ] GC(3) Major Collection (Warmup) 8960M(55%)->13184M(80%) 14.923s", + }; + List events = feedParser(eventLogEntries); + + assertEquals(4, events.size()); + + ZGCYoungCollection majorYoung = (ZGCYoungCollection) events.get(0); + assertEquals(3L, majorYoung.getGcId()); + assertEquals(GarbageCollectionTypes.ZGCMajorYoung, majorYoung.getGarbageCollectionType()); + + ZGCYoungCollection minorYoungA = (ZGCYoungCollection) events.get(1); + assertEquals(4L, minorYoungA.getGcId()); + assertEquals(GarbageCollectionTypes.ZGCMinorYoung, minorYoungA.getGarbageCollectionType()); + + ZGCYoungCollection minorYoungB = (ZGCYoungCollection) events.get(2); + assertEquals(5L, minorYoungB.getGcId()); + assertEquals(GarbageCollectionTypes.ZGCMinorYoung, minorYoungB.getGarbageCollectionType()); + + ZGCOldCollection majorOld = (ZGCOldCollection) events.get(3); + assertEquals(3L, majorOld.getGcId()); + assertEquals(GarbageCollectionTypes.ZGCMajorOld, majorOld.getGarbageCollectionType()); + + } + private boolean checkReferenceSummary(ZGCReferenceSummary refSummary, long encounderted, long discovered, long enqueued) { return refSummary.getEncountered() == encounderted && refSummary.getDiscovered() == discovered && refSummary.getEnqueued() == enqueued; } diff --git a/parser/src/test/java/com/microsoft/gctoolkit/parser/ZGCParserRulesTest.java b/parser/src/test/java/com/microsoft/gctoolkit/parser/ZGCParserRulesTest.java index f8b5947d..e4f83fee 100644 --- a/parser/src/test/java/com/microsoft/gctoolkit/parser/ZGCParserRulesTest.java +++ b/parser/src/test/java/com/microsoft/gctoolkit/parser/ZGCParserRulesTest.java @@ -83,7 +83,9 @@ private void evaluate(GCParseRule rule, String string, boolean dump) { MEMORY_TABLE_ENTRY_SIZE, MEMORY_TABLE_ENTRY_OCCUPANCY, MEMORY_TABLE_ENTRY_RECLAIMED_PROMOTED, - MEMORY_SUMMARY + MEMORY_SUMMARY, + GENERATION_START, // 15 + END_OF_PHASE_SUMMARY_GEN, }; private String[][] lines = { @@ -148,6 +150,19 @@ private void evaluate(GCParseRule rule, String string, boolean dump) { }, { // 14 "[32.193s][info][gc ] GC(2) Garbage Collection (Metadata GC Threshold) 558M(2%)->126M(0%)", + }, + { // 15 + "[2024-11-19T09:48:57.431-0600][info ][gc,phases ] GC(6) Y: Young Generation (Promote All)", + "[2024-11-19T09:48:42.508-0600][info ][gc,phases ] GC(3) Y: Young Generation", + "[2024-11-19T09:48:31.984-0600][info][gc,phases ] GC(0) O: Old Generation", + "[2024-11-19T09:48:52.855-0600][info ][gc,phases ] GC(5) y: Young Generation" + }, + { // 16 + "[2024-11-19T09:48:31.984-0600][info][gc,phases ] GC(0) Y: Young Generation 88M(1%)->54M(0%) 0.017s", + "[2024-11-19T09:49:02.950-0600][info ][gc,phases ] GC(6) Y: Young Generation (Promote All) 13184M(80%)->16384M(100%) 5.519s", + "[2024-11-19T09:48:31.997-0600][info][gc,phases ] GC(0) O: Old Generation 54M(0%)->56M(0%) 0.013s", + "[2024-11-19T09:48:52.821-0600][info ][gc,phases ] GC(4) y: Young Generation 13310M(81%)->15654M(96%) 4.926s", + "[2025-02-11T13:07:13.256-0800][info][gc,phases ] GC(7) y: Young Generation 14720M(40%)->2054M(6%) 0.689s", } }; diff --git a/parser/src/test/java/com/microsoft/gctoolkit/parser/ZGCParserTest.java b/parser/src/test/java/com/microsoft/gctoolkit/parser/ZGCParserTest.java index 6b2735ca..ab8be0eb 100644 --- a/parser/src/test/java/com/microsoft/gctoolkit/parser/ZGCParserTest.java +++ b/parser/src/test/java/com/microsoft/gctoolkit/parser/ZGCParserTest.java @@ -3,8 +3,8 @@ package com.microsoft.gctoolkit.parser; import com.microsoft.gctoolkit.event.jvm.JVMEvent; -import com.microsoft.gctoolkit.event.zgc.FullZGCCycle; import com.microsoft.gctoolkit.event.zgc.ZGCAllocatedSummary; +import com.microsoft.gctoolkit.event.zgc.ZGCFullCollection; import com.microsoft.gctoolkit.event.zgc.ZGCGarbageSummary; import com.microsoft.gctoolkit.event.zgc.ZGCLiveSummary; import com.microsoft.gctoolkit.event.zgc.ZGCMemoryPoolSummary; @@ -75,7 +75,7 @@ public void infoLevelZGCCycle() { List singleCycle = feedParser(eventLogEntries); try { assertEquals(1, singleCycle.size()); - FullZGCCycle zgc = (FullZGCCycle) singleCycle.get(0); + ZGCFullCollection zgc = (ZGCFullCollection) singleCycle.get(0); assertEquals(zgc.getGcId(), 2L); diff --git a/sample/src/main/java/com/microsoft/gctoolkit/sample/aggregation/CollectionCycleCountsAggregator.java b/sample/src/main/java/com/microsoft/gctoolkit/sample/aggregation/CollectionCycleCountsAggregator.java index 6f7eedaf..5bfa645d 100644 --- a/sample/src/main/java/com/microsoft/gctoolkit/sample/aggregation/CollectionCycleCountsAggregator.java +++ b/sample/src/main/java/com/microsoft/gctoolkit/sample/aggregation/CollectionCycleCountsAggregator.java @@ -7,9 +7,9 @@ import com.microsoft.gctoolkit.event.g1gc.G1GCPauseEvent; import com.microsoft.gctoolkit.event.generational.GenerationalGCPauseEvent; import com.microsoft.gctoolkit.event.shenandoah.ShenandoahCycle; -import com.microsoft.gctoolkit.event.zgc.FullZGCCycle; -import com.microsoft.gctoolkit.event.zgc.MajorZGCCycle; -import com.microsoft.gctoolkit.event.zgc.MinorZGCCycle; +import com.microsoft.gctoolkit.event.zgc.ZGCFullCollection; +import com.microsoft.gctoolkit.event.zgc.ZGCOldCollection; +import com.microsoft.gctoolkit.event.zgc.ZGCYoungCollection; @Aggregates({EventSource.G1GC,EventSource.GENERATIONAL,EventSource.ZGC,EventSource.SHENANDOAH}) public class CollectionCycleCountsAggregator extends Aggregator { @@ -19,21 +19,21 @@ public CollectionCycleCountsAggregator(CollectionCycleCountsAggregation results) register(GenerationalGCPauseEvent.class, this::count); register(G1GCPauseEvent.class, this::count); register(G1GCConcurrentEvent.class, this::count); - register(FullZGCCycle.class,this::count); - register(MajorZGCCycle.class,this::count); - register(MinorZGCCycle.class,this::count); + register(ZGCFullCollection.class, this::count); + register(ZGCOldCollection.class, this::count); + register(ZGCYoungCollection.class, this::count); register(ShenandoahCycle.class,this::count); } - private void count(MinorZGCCycle event) { + private void count(ZGCYoungCollection event) { aggregation().count(event.getGarbageCollectionType()); } - private void count(MajorZGCCycle event) { + private void count(ZGCOldCollection event) { aggregation().count(event.getGarbageCollectionType()); } - private void count(FullZGCCycle event) { + private void count(ZGCFullCollection event) { aggregation().count(event.getGarbageCollectionType()); } diff --git a/sample/src/main/java/com/microsoft/gctoolkit/sample/aggregation/HeapOccupancyAfterCollection.java b/sample/src/main/java/com/microsoft/gctoolkit/sample/aggregation/HeapOccupancyAfterCollection.java index ac787e96..c1c800c5 100644 --- a/sample/src/main/java/com/microsoft/gctoolkit/sample/aggregation/HeapOccupancyAfterCollection.java +++ b/sample/src/main/java/com/microsoft/gctoolkit/sample/aggregation/HeapOccupancyAfterCollection.java @@ -6,9 +6,9 @@ import com.microsoft.gctoolkit.event.g1gc.G1GCPauseEvent; import com.microsoft.gctoolkit.event.generational.GenerationalGCPauseEvent; import com.microsoft.gctoolkit.event.shenandoah.ShenandoahCycle; -import com.microsoft.gctoolkit.event.zgc.FullZGCCycle; -import com.microsoft.gctoolkit.event.zgc.MajorZGCCycle; -import com.microsoft.gctoolkit.event.zgc.MinorZGCCycle; +import com.microsoft.gctoolkit.event.zgc.ZGCFullCollection; +import com.microsoft.gctoolkit.event.zgc.ZGCOldCollection; +import com.microsoft.gctoolkit.event.zgc.ZGCYoungCollection; @Aggregates({EventSource.G1GC,EventSource.GENERATIONAL,EventSource.ZGC,EventSource.SHENANDOAH}) public class HeapOccupancyAfterCollection extends Aggregator { @@ -17,17 +17,17 @@ public HeapOccupancyAfterCollection(HeapOccupancyAfterCollectionAggregation resu super(results); register(GenerationalGCPauseEvent.class, this::extractHeapOccupancy); register(G1GCPauseEvent.class, this::extractHeapOccupancy); - register(FullZGCCycle.class,this::extractHeapOccupancy); - register(MajorZGCCycle.class,this::extractHeapOccupancy); - register(MinorZGCCycle.class,this::extractHeapOccupancy); + register(ZGCFullCollection.class, this::extractHeapOccupancy); + register(ZGCOldCollection.class, this::extractHeapOccupancy); + register(ZGCYoungCollection.class, this::extractHeapOccupancy); register(ShenandoahCycle.class,this::extractHeapOccupancy); } - private void extractHeapOccupancy(MinorZGCCycle event) { + private void extractHeapOccupancy(ZGCYoungCollection event) { aggregation().addDataPoint(event.getGarbageCollectionType(), event.getDateTimeStamp(), event.getMemorySummary().getOccupancyAfter()); } - private void extractHeapOccupancy(MajorZGCCycle event) { + private void extractHeapOccupancy(ZGCOldCollection event) { aggregation().addDataPoint(event.getGarbageCollectionType(), event.getDateTimeStamp(), event.getMemorySummary().getOccupancyAfter()); } @@ -40,7 +40,7 @@ private void extractHeapOccupancy(G1GCPauseEvent event) { } - private void extractHeapOccupancy(FullZGCCycle event) { + private void extractHeapOccupancy(ZGCFullCollection event) { aggregation().addDataPoint(event.getGarbageCollectionType(), event.getDateTimeStamp(), event.getMemorySummary().getOccupancyAfter()); }