@@ -421,14 +421,15 @@ private static Collection<HeapViewerNode> computeInstanceRoots(Instance instance
421
421
422
422
private static Collection <HeapViewerNode > computeInstancesRoots (Iterator <Instance > instances , int count , Progress progress ) throws InterruptedException {
423
423
Map <Instance , HeapViewerNode > gcRoots = new HashMap ();
424
+ Map <Instance ,Instance > gcRootCache = new HashMap <>();
424
425
425
426
try {
426
427
progress .setupKnownSteps (count );
427
428
428
429
Thread current = Thread .currentThread ();
429
430
while (!current .isInterrupted () && instances .hasNext ()) {
430
431
Instance instance = instances .next ();
431
- Instance gcRoot = getGCRoot (instance , current );
432
+ Instance gcRoot = getGCRoot (instance , current , gcRootCache );
432
433
GCRootNode gcRootNode = (GCRootNode )gcRoots .get (gcRoot );
433
434
if (gcRootNode == null ) {
434
435
gcRootNode = new GCRootNode (gcRoot );
@@ -450,11 +451,23 @@ private static Collection<HeapViewerNode> computeInstancesRoots(Iterator<Instanc
450
451
else return Collections .singleton (new TextNode (Bundle .PathToGCRootPlugin_NoRoot ()));
451
452
}
452
453
453
- private static Instance getGCRoot (Instance instance , Thread current ) {
454
- Instance previousInstance = null ;
455
- while (!current .isInterrupted () && instance != null && instance != previousInstance ) {
456
- previousInstance = instance ;
454
+ private static final int MARKER_DISTANCE = 1000 ;
455
+ private static Instance getGCRoot (Instance instance , Thread current , Map <Instance ,Instance > cache ) {
456
+ List <Instance > markers = new ArrayList <>();
457
+ int i = 1 ;
458
+ while (!instance .isGCRoot ()) {
459
+ // check cache first
460
+ Instance gcRoot = cache .get (instance );
461
+ if (gcRoot != null ) {
462
+ instance = gcRoot ;
463
+ break ;
464
+ }
465
+ if (i ++ % MARKER_DISTANCE == 0 ) markers .add (instance );
457
466
instance = instance .getNearestGCRootPointer ();
467
+ if (current .isInterrupted () || instance == null ) return null ;
468
+ }
469
+ for (Instance m : markers ) {
470
+ cache .put (m , instance );
458
471
}
459
472
return instance ;
460
473
}
0 commit comments