// Check some basics. // This thread is not the main thread.
jthread this_thread;
jvmtiError this_thread_result = jenv->GetCurrentThread(&this_thread);
CheckJvmtiError(jenv, this_thread_result);
CHECK(!env->IsSameObject(this_thread, data->main_thread));
// The thread is a daemon.
jvmtiThreadInfo info;
jvmtiError info_result = jenv->GetThreadInfo(this_thread, &info);
CheckJvmtiError(jenv, info_result);
CHECK(info.is_daemon);
CheckJvmtiError(jenv, jenv->Deallocate(reinterpret_cast<unsignedchar*>(info.name))); if (info.thread_group != nullptr) {
env->DeleteLocalRef(info.thread_group);
} if (info.context_class_loader != nullptr) {
env->DeleteLocalRef(info.context_class_loader);
}
// The thread has the requested priority. // TODO: Our thread priorities do not work on the host. // CHECK_EQ(info.priority, data->priority);
// Check further parts of the thread:
jint thread_count;
jthread* threads;
jvmtiError threads_result = jenv->GetAllThreads(&thread_count, &threads);
CheckJvmtiError(jenv, threads_result); bool found = false; for (jint i = 0; i != thread_count; ++i) { if (env->IsSameObject(threads[i], this_thread)) {
found = true; break;
}
}
CHECK(found);
// Done, let the main thread progress. int wait_result = pthread_barrier_wait(&data->b);
CHECK(wait_result == PTHREAD_BARRIER_SERIAL_THREAD || wait_result == 0);
}
ScopedLocalRef<jclass> thread_klass(env, env->FindClass("java/lang/Thread")); if (thread_klass.get() == nullptr) { return;
}
ScopedLocalRef<jobject> thread(env, env->AllocObject(thread_klass.get())); if (thread.get() == nullptr) { return;
}
// Get a ThreadGroup from the current thread. We need a non-null one as we're gonna call a // runtime-only constructor (so we can set priority and daemon state).
jvmtiThreadInfo cur_thread_info;
jvmtiError info_result = jvmti_env->GetThreadInfo(nullptr, &cur_thread_info); if (JvmtiErrorToException(env, jvmti_env, info_result)) { return;
}
CheckJvmtiError(jvmti_env,
jvmti_env->Deallocate(reinterpret_cast<unsignedchar*>(cur_thread_info.name)));
ScopedLocalRef<jobject> thread_group(env, cur_thread_info.thread_group); if (cur_thread_info.context_class_loader != nullptr) {
env->DeleteLocalRef(cur_thread_info.context_class_loader);
}
// Scheduling may mean that the agent thread is put to sleep. Wait until it's dead in an effort // to not unload the plugin and crash. for (;;) {
sleep(1);
jint thread_state;
jvmtiError state_result = jvmti_env->GetThreadState(thread.get(), &thread_state); if (JvmtiErrorToException(env, jvmti_env, state_result)) { return;
} if (thread_state == 0 || // Was never alive.
(thread_state & JVMTI_THREAD_STATE_TERMINATED) != 0) { // Was alive and died. break;
}
} // Yield and sleep a bit more, to give the plugin time to tear down the native thread structure.
sched_yield();
sleep(1);
env->DeleteGlobalRef(data.main_thread);
pthread_barrier_destroy(&data.b);
}
} // namespace Test930AgentThread
} // namespace art
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet am 2026-06-29)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.