26
26
package org .graalvm .visualvm .heapviewer .java .impl ;
27
27
28
28
import java .util .ArrayList ;
29
+ import java .util .Collection ;
29
30
import java .util .HashMap ;
30
31
import java .util .HashSet ;
31
32
import java .util .Iterator ;
32
33
import java .util .List ;
33
34
import java .util .Map ;
34
35
import java .util .Set ;
36
+ import java .util .stream .Collectors ;
35
37
import javax .swing .SortOrder ;
36
38
import org .graalvm .visualvm .lib .jfluid .heap .GCRoot ;
37
39
import org .graalvm .visualvm .lib .jfluid .heap .Heap ;
@@ -168,18 +170,22 @@ private static String getNoItemsString(HeapViewerNodeFilter viewFilter) {
168
170
}
169
171
170
172
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 ());
172
178
173
179
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 ) {
175
181
protected boolean sorts (DataType dataType ) {
176
182
return !DataType .COUNT .equals (dataType );
177
183
}
178
- protected HeapViewerNode createNode (GCRoot gcRoot ) {
179
- return new InstanceNode (gcRoot . getInstance () );
184
+ protected HeapViewerNode createNode (Instance gcRootInstance ) {
185
+ return new InstanceNode (gcRootInstance );
180
186
}
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 );
183
189
return new ProgressIterator (iterator , index , false , progress );
184
190
}
185
191
protected String getMoreNodesString (String moreNodesCount ) {
@@ -196,32 +202,37 @@ protected String getNodesContainerString(String firstNodeIdx, String lastNodeIdx
196
202
return nodes .length == 0 ? new HeapViewerNode [] { new TextNode (GCRoots_Messages .getNoItemsString (viewFilter )) } : nodes ;
197
203
} else {
198
204
if (viewFilter != null ) {
199
- Iterator <GCRoot > gcrootsI = gcroots .iterator ();
205
+ Iterator <Instance > gcrootsI = gcrootInstances .iterator ();
200
206
while (gcrootsI .hasNext ())
201
- if (!viewFilter .passes (new InstanceNode (gcrootsI .next (). getInstance () ), heap ))
207
+ if (!viewFilter .passes (new InstanceNode (gcrootsI .next ()), heap ))
202
208
gcrootsI .remove ();
203
209
}
204
210
205
211
if (aggregation == 3 ) {
206
212
List <GCTypeNode > tnodes = new ArrayList ();
207
213
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
+ }
215
228
}
216
- tnode .add (gcroot .getInstance (), heap );
217
229
}
218
230
return tnodes .isEmpty () ? new HeapViewerNode [] { new TextNode (GCRoots_Messages .getNoItemsString (viewFilter )) } :
219
231
tnodes .toArray (HeapViewerNode .NO_NODES );
220
232
} else {
221
233
List <InstancesContainer .Objects > cnodes = new ArrayList ();
222
234
Map <String , InstancesContainer .Objects > classes = new HashMap ();
223
- for (GCRoot gcroot : gcroots ) {
224
- Instance instance = gcroot .getInstance ();
235
+ for (Instance instance : gcrootInstances ) {
225
236
JavaClass javaClass = instance .getJavaClass ();
226
237
String className = javaClass .getName ();
227
238
InstancesContainer .Objects cnode = classes .get (className );
0 commit comments