Skip to content

Commit daf82ab

Browse files
committed
GH-255, duplicate nodes fixed - Heap.getGCRoots() returns all GCRoots including duplicates (issue 215)
1 parent aceced5 commit daf82ab

File tree

1 file changed

+29
-18
lines changed

1 file changed

+29
-18
lines changed

visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/java/impl/JavaClassesProvider.java

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,14 @@
2626
package org.graalvm.visualvm.heapviewer.java.impl;
2727

2828
import java.util.ArrayList;
29+
import java.util.Collection;
2930
import java.util.HashMap;
3031
import java.util.HashSet;
3132
import java.util.Iterator;
3233
import java.util.List;
3334
import java.util.Map;
3435
import java.util.Set;
36+
import java.util.stream.Collectors;
3537
import javax.swing.SortOrder;
3638
import org.graalvm.visualvm.lib.jfluid.heap.GCRoot;
3739
import org.graalvm.visualvm.lib.jfluid.heap.Heap;
@@ -168,18 +170,22 @@ private static String getNoItemsString(HeapViewerNodeFilter viewFilter) {
168170
}
169171

170172
public static HeapViewerNode[] getHeapGCRoots(HeapViewerNode parent, Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress, int aggregation) throws InterruptedException {
171-
final List<GCRoot> gcroots = new ArrayList(heap.getGCRoots());
173+
final Collection<GCRoot> gcroots = heap.getGCRoots();
174+
final List<Instance> gcrootInstances = gcroots.stream()
175+
.map(GCRoot::getInstance)
176+
.distinct()
177+
.collect(Collectors.toList());
172178

173179
if (aggregation == 0) {
174-
NodesComputer<GCRoot> computer = new NodesComputer<GCRoot>(gcroots.size(), UIThresholds.MAX_TOPLEVEL_INSTANCES) {
180+
NodesComputer<Instance> computer = new NodesComputer<Instance>(gcrootInstances.size(), UIThresholds.MAX_TOPLEVEL_INSTANCES) {
175181
protected boolean sorts(DataType dataType) {
176182
return !DataType.COUNT.equals(dataType);
177183
}
178-
protected HeapViewerNode createNode(GCRoot gcRoot) {
179-
return new InstanceNode(gcRoot.getInstance());
184+
protected HeapViewerNode createNode(Instance gcRootInstance) {
185+
return new InstanceNode(gcRootInstance);
180186
}
181-
protected ProgressIterator<GCRoot> objectsIterator(int index, Progress progress) {
182-
Iterator<GCRoot> iterator = gcroots.listIterator(index);
187+
protected ProgressIterator<Instance> objectsIterator(int index, Progress progress) {
188+
Iterator<Instance> iterator = gcrootInstances.listIterator(index);
183189
return new ProgressIterator(iterator, index, false, progress);
184190
}
185191
protected String getMoreNodesString(String moreNodesCount) {
@@ -196,32 +202,37 @@ protected String getNodesContainerString(String firstNodeIdx, String lastNodeIdx
196202
return nodes.length == 0 ? new HeapViewerNode[] { new TextNode(GCRoots_Messages.getNoItemsString(viewFilter)) } : nodes;
197203
} else {
198204
if (viewFilter != null) {
199-
Iterator<GCRoot> gcrootsI = gcroots.iterator();
205+
Iterator<Instance> gcrootsI = gcrootInstances.iterator();
200206
while (gcrootsI.hasNext())
201-
if (!viewFilter.passes(new InstanceNode(gcrootsI.next().getInstance()), heap))
207+
if (!viewFilter.passes(new InstanceNode(gcrootsI.next()), heap))
202208
gcrootsI.remove();
203209
}
204210

205211
if (aggregation == 3) {
206212
List<GCTypeNode> tnodes = new ArrayList();
207213
Map<String, GCTypeNode> types = new HashMap();
208-
for (GCRoot gcroot : gcroots) {
209-
String tname = gcroot.getKind();
210-
GCTypeNode tnode = types.get(tname);
211-
if (tnode == null) {
212-
tnode = new GCTypeNode(tname);
213-
tnodes.add(tnode);
214-
types.put(tname, tnode);
214+
for (Instance instance : gcrootInstances) {
215+
Collection<GCRoot> igcroots = (Collection<GCRoot>)heap.getGCRoots(instance);
216+
Set<String> typeSet = new HashSet();
217+
for (GCRoot gcroot : igcroots) {
218+
String tname = gcroot.getKind();
219+
if (typeSet.add(tname)) {
220+
GCTypeNode tnode = types.get(tname);
221+
if (tnode == null) {
222+
tnode = new GCTypeNode(tname);
223+
tnodes.add(tnode);
224+
types.put(tname, tnode);
225+
}
226+
tnode.add(gcroot.getInstance(), heap);
227+
}
215228
}
216-
tnode.add(gcroot.getInstance(), heap);
217229
}
218230
return tnodes.isEmpty() ? new HeapViewerNode[] { new TextNode(GCRoots_Messages.getNoItemsString(viewFilter)) } :
219231
tnodes.toArray(HeapViewerNode.NO_NODES);
220232
} else {
221233
List<InstancesContainer.Objects> cnodes = new ArrayList();
222234
Map<String, InstancesContainer.Objects> classes = new HashMap();
223-
for (GCRoot gcroot : gcroots) {
224-
Instance instance = gcroot.getInstance();
235+
for (Instance instance : gcrootInstances) {
225236
JavaClass javaClass = instance.getJavaClass();
226237
String className = javaClass.getName();
227238
InstancesContainer.Objects cnode = classes.get(className);

0 commit comments

Comments
 (0)