JVMTI のイベントの中には, 実際にそのイベントが起こった瞬間ではなく, 少し遅れてから通知されるものがある.
(現状の HotSpot の実装では, CompiledMethodLoad, CompiledMethodUnload, DynamicCodeGenerated が遅延配送される模様)
これらのイベントを遅延させているのは, イベント通知は JavaThread から行わないといけないが, これらのイベントは CompilerThread や VMThread の中で発生するものであるため.
そのため, CompilerThread や VMThread 内ではイベントが発生したという情報だけを記録しておき, "ServiceThread" という JavaThread が実際の通知処理を行うことにしている.
((cite: hotspot/src/share/vm/prims/jvmtiImpl.hpp))
/**
* When a thread (such as the compiler thread or VM thread) cannot post a
* JVMTI event itself because the event needs to be posted from a Java
* thread, then it can defer the event to the Service thread for posting.
* The information needed to post the event is encapsulated into this class
* and then enqueued onto the JvmtiDeferredEventQueue, where the Service
* thread will pick it up and post it.
*
* This is currently only used for posting compiled-method-load and unload
* events, which we don't want posted from the compiler thread.
*/
以下のクラス群によって遅延通知が実現されている.
すぐに post できないイベントが発生すると, そのイベントの内容を格納した JvmtiDeferredEvent オブジェクトが作られ, JvmtiDeferredEventQueue に格納される.
この JvmtiDeferredEventQueue は ServiceThread によって監視されており, JvmtiDeferredEvent オブジェクトが追加されると ServiceThread がそれを取り出して JvmtiDeferredEvent::post() を呼び出すことでイベント通知処理を実行する.
(略) (See: here for details) -> ciEnv::register_method() -> nmethod::post_compiled_method_load_event() -> nmethod::get_and_cache_jmethod_id() -> JvmtiDeferredEvent::compiled_method_load_event() -> JvmtiDeferredEventQueue::enqueue() (略) (See: here for details) -> AdapterHandlerLibrary::create_native_wrapper() -> nmethod::post_compiled_method_load_event() -> (同上)
(略) (See: ...) -> nmethod::make_unloaded() -> nmethod::post_compiled_method_unload() -> JvmtiDeferredEvent::compiled_method_unload_event() -> * safepoint 中の場合 -> JvmtiDeferredEventQueue::add_pending_event() * そうではない場合 -> JvmtiDeferredEventQueue::enqueue() (略) (See: ...) -> nmethod::make_not_entrant_or_zombie() -> nmethod::post_compiled_method_unload() -> (同上)
JvmtiExport::post_dynamic_code_generated(const char *name, const void *code_begin, const void *code_end) -> * HotSpot の起動中の場合: -> JvmtiExport::post_dynamic_code_generated_internal() * それ以外の場合: -> JvmtiDeferredEvent::dynamic_code_generated_event() -> JvmtiDeferredEventQueue::enqueue()
ServiceThread::service_thread_entry() -> JvmtiDeferredEventQueue::has_events() -> JvmtiDeferredEventQueue::dequeue() -> JvmtiDeferredEvent::post() -> * CompiledMethodLoad の場合: -> JvmtiExport::post_compiled_method_load() * CompiledMethodUnload の場合: -> JvmtiExport::post_compiled_method_unload() * DynamicCodeGenerated の場合: -> JvmtiExport::post_dynamic_code_generated_internal()
See: here for details
See: here for details
See: here for details
(#Under Construction) See: here for details
(#Under Construction) See: here for details
(#Under Construction) See: here for details
See: here for details
(#Under Construction) See: here for details
(#Under Construction)
See: here for details
See: here for details
See: here for details
(#Under Construction) See: here for details
See: here for details
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.