Skip to content

Commit 516748a

Browse files
committed
GH-569 cache added to speed up computation of GC Root-s
1 parent b5fe678 commit 516748a

File tree

1 file changed

+18
-5
lines changed

1 file changed

+18
-5
lines changed

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

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -421,14 +421,15 @@ private static Collection<HeapViewerNode> computeInstanceRoots(Instance instance
421421

422422
private static Collection<HeapViewerNode> computeInstancesRoots(Iterator<Instance> instances, int count, Progress progress) throws InterruptedException {
423423
Map<Instance, HeapViewerNode> gcRoots = new HashMap();
424+
Map<Instance,Instance> gcRootCache = new HashMap<>();
424425

425426
try {
426427
progress.setupKnownSteps(count);
427428

428429
Thread current = Thread.currentThread();
429430
while (!current.isInterrupted() && instances.hasNext()) {
430431
Instance instance = instances.next();
431-
Instance gcRoot = getGCRoot(instance, current);
432+
Instance gcRoot = getGCRoot(instance, current, gcRootCache);
432433
GCRootNode gcRootNode = (GCRootNode)gcRoots.get(gcRoot);
433434
if (gcRootNode == null) {
434435
gcRootNode = new GCRootNode(gcRoot);
@@ -450,11 +451,23 @@ private static Collection<HeapViewerNode> computeInstancesRoots(Iterator<Instanc
450451
else return Collections.singleton(new TextNode(Bundle.PathToGCRootPlugin_NoRoot()));
451452
}
452453

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);
457466
instance = instance.getNearestGCRootPointer();
467+
if (current.isInterrupted() || instance == null) return null;
468+
}
469+
for (Instance m : markers) {
470+
cache.put(m, instance);
458471
}
459472
return instance;
460473
}

0 commit comments

Comments
 (0)