2626package org .graalvm .visualvm .heapviewer .java .impl ;
2727
2828import java .util .ArrayList ;
29+ import java .util .Collection ;
2930import java .util .HashMap ;
3031import java .util .HashSet ;
3132import java .util .Iterator ;
3233import java .util .List ;
3334import java .util .Map ;
3435import java .util .Set ;
36+ import java .util .stream .Collectors ;
3537import javax .swing .SortOrder ;
3638import org .graalvm .visualvm .lib .jfluid .heap .GCRoot ;
3739import 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