Skip to content

Commit 97cd12d

Browse files
committed
GH-336 use int[] for 'threadSerialNumber' -> 'index' map
1 parent 9d37e9f commit 97cd12d

File tree

1 file changed

+34
-5
lines changed
  • visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/heap

1 file changed

+34
-5
lines changed

visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/heap/HprofGCRoots.java

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ class HprofGCRoots {
3939

4040
final HprofHeap heap;
4141
final private Object threadSerialMapLock = new Object();
42-
private LongHashMap threadSerialMap;
42+
private ThreadMap threadSerialMap;
4343
private int rootThreadsCount;
4444
private Map gcRoots;
4545
final private Object gcRootLock = new Object();
@@ -93,17 +93,16 @@ ThreadObjectGCRoot getThreadGCRoot(int threadSerialNumber) {
9393
List<GCRoot> roots = getGCRoots();
9494
synchronized (threadSerialMapLock) {
9595
if (threadSerialMap == null) {
96-
threadSerialMap = new LongHashMap(rootThreadsCount);
96+
threadSerialMap = new ThreadMap(rootThreadsCount);
9797

9898
for (int i = 0; i < roots.size(); i++) {
9999
GCRoot gcRoot = roots.get(i);
100100
if (gcRoot instanceof ThreadObjectHprofGCRoot) {
101-
ThreadObjectHprofGCRoot threadObjGC = (ThreadObjectHprofGCRoot) gcRoot;
102-
threadSerialMap.put(threadObjGC.getThreadSerialNumber(), i);
101+
threadSerialMap.putThreadIndex((ThreadObjectHprofGCRoot) gcRoot, i);
103102
}
104103
}
105104
}
106-
int threadIndex = (int)threadSerialMap.get(threadSerialNumber);
105+
int threadIndex = threadSerialMap.getThreadIndex(threadSerialNumber);
107106

108107
if (threadIndex != -1) {
109108
return (ThreadObjectGCRoot)roots.get(threadIndex);
@@ -150,4 +149,34 @@ private void computeGCRootsFor(TagBounds tagBounds) {
150149
}
151150
}
152151
}
152+
153+
private static class ThreadMap {
154+
private final int[] serialMap;
155+
// gracefully handle hprof dumps, which does not follow spec -
156+
// thread serial number should be sequential starting from 1
157+
private final Map<Integer,Integer> serialMapOverflow = new HashMap();
158+
159+
ThreadMap(int threadCount) {
160+
serialMap = new int[threadCount+1];
161+
}
162+
163+
private void putThreadIndex(ThreadObjectHprofGCRoot threadGCRoot, int index) {
164+
int serialNum = threadGCRoot.getThreadSerialNumber();
165+
if (serialNum < serialMap.length) {
166+
serialMap[serialNum] = index;
167+
} else {
168+
serialMapOverflow.put(serialNum, index);
169+
}
170+
}
171+
172+
private int getThreadIndex(int serialNum) {
173+
if (serialNum >= 0 && serialNum < serialMap.length) {
174+
return serialMap[serialNum];
175+
} else {
176+
Integer threadIndexObj = serialMapOverflow.get(serialNum);
177+
if (threadIndexObj == null) return -1;
178+
return threadIndexObj.intValue();
179+
}
180+
}
181+
}
153182
}

0 commit comments

Comments
 (0)