@@ -39,7 +39,7 @@ class HprofGCRoots {
39
39
40
40
final HprofHeap heap ;
41
41
final private Object threadSerialMapLock = new Object ();
42
- private LongHashMap threadSerialMap ;
42
+ private ThreadMap threadSerialMap ;
43
43
private int rootThreadsCount ;
44
44
private Map gcRoots ;
45
45
final private Object gcRootLock = new Object ();
@@ -93,17 +93,16 @@ ThreadObjectGCRoot getThreadGCRoot(int threadSerialNumber) {
93
93
List <GCRoot > roots = getGCRoots ();
94
94
synchronized (threadSerialMapLock ) {
95
95
if (threadSerialMap == null ) {
96
- threadSerialMap = new LongHashMap (rootThreadsCount );
96
+ threadSerialMap = new ThreadMap (rootThreadsCount );
97
97
98
98
for (int i = 0 ; i < roots .size (); i ++) {
99
99
GCRoot gcRoot = roots .get (i );
100
100
if (gcRoot instanceof ThreadObjectHprofGCRoot ) {
101
- ThreadObjectHprofGCRoot threadObjGC = (ThreadObjectHprofGCRoot ) gcRoot ;
102
- threadSerialMap .put (threadObjGC .getThreadSerialNumber (), i );
101
+ threadSerialMap .putThreadIndex ((ThreadObjectHprofGCRoot ) gcRoot , i );
103
102
}
104
103
}
105
104
}
106
- int threadIndex = ( int ) threadSerialMap .get (threadSerialNumber );
105
+ int threadIndex = threadSerialMap .getThreadIndex (threadSerialNumber );
107
106
108
107
if (threadIndex != -1 ) {
109
108
return (ThreadObjectGCRoot )roots .get (threadIndex );
@@ -150,4 +149,34 @@ private void computeGCRootsFor(TagBounds tagBounds) {
150
149
}
151
150
}
152
151
}
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
+ }
153
182
}
0 commit comments