@@ -169,12 +169,13 @@ void WallClockJVMTI::timerLoop() {
169169 return ;
170170 }
171171
172+ // Notice:
173+ // We want to cache threads that are captured by collectThread(), so that we can
174+ // clean them up in cleanThreadRefs().
175+ // The approach is not ideal, but it is cleaner than cleaning individual thread
176+ // during filtering phases.
172177 jint threads_count = 0 ;
173178 jthread* threads_ptr = nullptr ;
174- if (jvmti->GetAllThreads (&threads_count, &threads_ptr) != JVMTI_ERROR_NONE ||
175- threads_count == 0 ) {
176- return ;
177- }
178179
179180 // Attach to JVM as the first step
180181 VM::attachThread (" Datadog Profiler Wallclock Sampler" );
@@ -183,6 +184,12 @@ void WallClockJVMTI::timerLoop() {
183184 if (jvmti == nullptr ) {
184185 return ;
185186 }
187+
188+ if (jvmti->GetAllThreads (&threads_count, &threads_ptr) != JVMTI_ERROR_NONE ||
189+ threads_count == 0 ) {
190+ return ;
191+ }
192+
186193 JNIEnv* jni = VM::jni ();
187194
188195 ThreadFilter* threadFilter = Profiler::instance ()->threadFilter ();
@@ -239,13 +246,18 @@ void WallClockJVMTI::timerLoop() {
239246 return true ;
240247 };
241248
242- timerLoopCommon<ThreadEntry>(collectThreads, sampleThreads, _reservoir_size, _interval);
249+ auto cleanThreadRefs = [&]() {
250+ JNIEnv* jni = VM::jni ();
251+ for (jint index = 0 ; index < threads_count; index++) {
252+ jni->DeleteLocalRef (threads_ptr[index]);
253+ }
254+ jvmti->Deallocate ((unsigned char *)threads_ptr);
255+ threads_ptr = nullptr ;
256+ threads_count = 0 ;
257+ };
258+
259+ timerLoopCommon<ThreadEntry>(collectThreads, sampleThreads, cleanThreadRefs, _reservoir_size, _interval);
243260
244- JNIEnv* jni = VM::jni ();
245- for (jint index = 0 ; index < threads_count; index++) {
246- jni->DeleteLocalRef (threads_ptr[index]);
247- }
248- jvmti->Deallocate ((unsigned char *)threads_ptr);
249261
250262 // Don't forget to detach the thread
251263 VM::detachThread ();
@@ -285,5 +297,8 @@ void WallClockASGCT::timerLoop() {
285297 return true ;
286298 };
287299
288- timerLoopCommon<int >(collectThreads, sampleThreads, _reservoir_size, _interval);
300+ auto doNothing = []() {
301+ };
302+
303+ timerLoopCommon<int >(collectThreads, sampleThreads, doNothing, _reservoir_size, _interval);
289304}
0 commit comments