55
55
class HprofGCRoots {
56
56
57
57
final HprofHeap heap ;
58
- private ThreadObjectHprofGCRoot lastThreadObjGC ;
59
- final private Object lastThreadObjGCLock = new Object ();
58
+ final private Object threadSerialMapLock = new Object ();
59
+ private LongHashMap threadSerialMap ;
60
+ private int rootThreadsCount ;
60
61
private Map gcRoots ;
61
62
final private Object gcRootLock = new Object ();
62
- private List gcRootsList ;
63
+ private List < GCRoot > gcRootsList ;
63
64
64
65
HprofGCRoots (HprofHeap h ) {
65
66
heap = h ;
66
67
}
67
68
68
- Collection getGCRoots () {
69
+ List < GCRoot > getGCRoots () {
69
70
synchronized (gcRootLock ) {
70
71
if (gcRoots == null ) {
71
72
gcRoots = new HashMap (16384 );
@@ -106,20 +107,24 @@ Object getGCRoots(Long instanceId) {
106
107
}
107
108
108
109
ThreadObjectGCRoot getThreadGCRoot (int threadSerialNumber ) {
109
- synchronized ( lastThreadObjGCLock ) {
110
- if ( lastThreadObjGC != null && threadSerialNumber == lastThreadObjGC . getThreadSerialNumber () ) {
111
- return lastThreadObjGC ;
112
- }
110
+ List < GCRoot > roots = getGCRoots ();
111
+ synchronized ( threadSerialMapLock ) {
112
+ if ( threadSerialMap == null ) {
113
+ threadSerialMap = new LongHashMap ( rootThreadsCount );
113
114
114
- for (GCRoot gcRoot : heap .getGCRoots ()) {
115
- if (gcRoot instanceof ThreadObjectHprofGCRoot ) {
116
- ThreadObjectHprofGCRoot threadObjGC = (ThreadObjectHprofGCRoot ) gcRoot ;
117
- if (threadSerialNumber == threadObjGC .getThreadSerialNumber ()) {
118
- lastThreadObjGC = threadObjGC ;
119
- return threadObjGC ;
115
+ for (int i = 0 ; i < roots .size (); i ++) {
116
+ GCRoot gcRoot = roots .get (i );
117
+ if (gcRoot instanceof ThreadObjectHprofGCRoot ) {
118
+ ThreadObjectHprofGCRoot threadObjGC = (ThreadObjectHprofGCRoot ) gcRoot ;
119
+ threadSerialMap .put (threadObjGC .getThreadSerialNumber (), i );
120
120
}
121
121
}
122
122
}
123
+ int threadIndex = (int )threadSerialMap .get (threadSerialNumber );
124
+
125
+ if (threadIndex != -1 ) {
126
+ return (ThreadObjectGCRoot )roots .get (threadIndex );
127
+ }
123
128
return null ;
124
129
}
125
130
}
@@ -136,7 +141,8 @@ private void computeGCRootsFor(TagBounds tagBounds) {
136
141
if (heap .readDumpTag (offset ) == rootTag ) {
137
142
HprofGCRoot root ;
138
143
if (rootTag == HprofHeap .ROOT_THREAD_OBJECT ) {
139
- root = new ThreadObjectHprofGCRoot (this , start );
144
+ root = new ThreadObjectHprofGCRoot (this , start );
145
+ rootThreadsCount ++;
140
146
} else if (rootTag == HprofHeap .ROOT_JAVA_FRAME ) {
141
147
root = new JavaFrameHprofGCRoot (this , start );
142
148
} else if (rootTag == HprofHeap .ROOT_JNI_LOCAL ) {
0 commit comments