From 97e72c0e4e2c1508e1b002578fcb675baf7b57ee Mon Sep 17 00:00:00 2001 From: Denghui Dong Date: Sat, 31 Aug 2024 09:34:04 +0800 Subject: [PATCH] feat: show jvm options in heap dump overview --- .../java/org/eclipse/jifa/hda/api/Model.java | 13 ++--- .../jifa/hda/impl/HeapDumpAnalyzerImpl.java | 54 ++++++++++++++++--- frontend/src/components/heapdump/Overview.vue | 28 +++++----- frontend/src/i18n/heapdump/en.ts | 1 + frontend/src/i18n/heapdump/zh.ts | 1 + 5 files changed, 70 insertions(+), 27 deletions(-) diff --git a/analysis/heap-dump/api/src/main/java/org/eclipse/jifa/hda/api/Model.java b/analysis/heap-dump/api/src/main/java/org/eclipse/jifa/hda/api/Model.java index 63bcfb19..5d91c330 100644 --- a/analysis/heap-dump/api/src/main/java/org/eclipse/jifa/hda/api/Model.java +++ b/analysis/heap-dump/api/src/main/java/org/eclipse/jifa/hda/api/Model.java @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2021, 2023 Contributors to the Eclipse Foundation + * Copyright (c) 2021, 2024 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. @@ -754,8 +754,6 @@ public BigObject(String label, int objectId, double value, String description) { @Data class Details { - public String jvmInfo; - public int identifierSize; public long creationDate; @@ -770,13 +768,12 @@ class Details { public long usedHeapSize; - public boolean generationInfoAvailable; + public List jvmOptions; - public Details(String jvmInfo, int identifierSize, long creationDate, int numberOfObjects, + public Details(int identifierSize, long creationDate, int numberOfObjects, int numberOfGCRoots, int numberOfClasses, int numberOfClassLoaders, long usedHeapSize, - boolean generationInfoAvailable) { - this.jvmInfo = jvmInfo; + List jvmOptions) { this.identifierSize = identifierSize; this.creationDate = creationDate; this.numberOfObjects = numberOfObjects; @@ -784,7 +781,7 @@ public Details(String jvmInfo, int identifierSize, long creationDate, int number this.numberOfClasses = numberOfClasses; this.numberOfClassLoaders = numberOfClassLoaders; this.usedHeapSize = usedHeapSize; - this.generationInfoAvailable = generationInfoAvailable; + this.jvmOptions = jvmOptions; } } } diff --git a/analysis/heap-dump/impl/src/main/java/org/eclipse/jifa/hda/impl/HeapDumpAnalyzerImpl.java b/analysis/heap-dump/impl/src/main/java/org/eclipse/jifa/hda/impl/HeapDumpAnalyzerImpl.java index 01b6f83e..fb383583 100644 --- a/analysis/heap-dump/impl/src/main/java/org/eclipse/jifa/hda/impl/HeapDumpAnalyzerImpl.java +++ b/analysis/heap-dump/impl/src/main/java/org/eclipse/jifa/hda/impl/HeapDumpAnalyzerImpl.java @@ -72,7 +72,18 @@ import java.lang.ref.SoftReference; import java.net.URL; import java.nio.file.Path; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.StringTokenizer; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; import java.util.regex.Pattern; @@ -194,6 +205,14 @@ private static Map> convert(AnalysisContext context, } } + private static V $(RV rv, V def) { + try { + return rv.run(); + } catch (Throwable t) { + return def; + } + } + private static void $(R e) { $(() -> { e.run(); @@ -210,15 +229,38 @@ public void dispose() { public Overview.Details getDetails() { return $(() -> { SnapshotInfo snapshotInfo = context.snapshot.getSnapshotInfo(); - return new Overview.Details(snapshotInfo.getJvmInfo(), snapshotInfo.getIdentifierSize(), - snapshotInfo.getCreationDate().getTime(), snapshotInfo.getNumberOfObjects(), - snapshotInfo.getNumberOfGCRoots(), snapshotInfo.getNumberOfClasses(), - snapshotInfo.getNumberOfClassLoaders(), snapshotInfo.getUsedHeapSize(), - false); + return new Overview.Details(snapshotInfo.getIdentifierSize(), + snapshotInfo.getCreationDate().getTime(), + snapshotInfo.getNumberOfObjects(), + snapshotInfo.getNumberOfGCRoots(), + snapshotInfo.getNumberOfClasses(), + snapshotInfo.getNumberOfClassLoaders(), + snapshotInfo.getUsedHeapSize(), + getJVMOptions()); } ); } + private List getJVMOptions() { + return $(() -> { + List result = new ArrayList<>(); + IResult oqlResult = getOQLResult(context, "select v.vmArgs.list.a.@objectId from sun.management.VMManagementImpl v"); + if (oqlResult instanceof IResultTable t && t.getRowCount() == 1) { + Object row = t.getRow(0); + Integer id = (Integer) t.getColumnValue(row, 0); + IObjectArray array = (IObjectArray) context.snapshot.getObject(id); + long[] refs = array.getReferenceArray(); + for (long address : refs) { + if (address != 0) { + IObject object = context.snapshot.getObject(context.snapshot.mapAddressToId(address)); + result.add(object.getClassSpecificName()); + } + } + } + return result; + }, Collections.emptyList()); + } + private Res queryByCommand(AnalysisContext context, String command) throws SnapshotException { return queryByCommand(context, command, null, NoOpProgressListener); diff --git a/frontend/src/components/heapdump/Overview.vue b/frontend/src/components/heapdump/Overview.vue index b0b11e24..bd729363 100644 --- a/frontend/src/components/heapdump/Overview.vue +++ b/frontend/src/components/heapdump/Overview.vue @@ -1,5 +1,5 @@