JVMTI 是 JVM 提供给本地(C/C++)agent 的诊断接口,调试器与各种 profiler 都建立在它上面。这篇自己写一个最小的 JVMTI agent,看它到底能观察到什么(Java 层的 Instrumentation 在前面一篇,Attach 与 HotSwap 在后面)。
[app] 结束,持有 1234 个 Foo
[jvmti] Agent_OnLoad:AddCapabilities(can_tag_objects, can_generate_garbage_collection_events) → 错误码 0(0 = 成功) [jvmti] 这个 JVM 在 OnLoad 阶段可申请的能力一共 68 项 [app] 结束,持有 1234 个 Foo [jvmti] VMDeath:GetLoadedClasses 返回 661 个类 [jvmti] 遍历堆:app.Foo 的实例有 1234 个(包括还没被回收的) [jvmti] 存活的 Java 线程 6 个:Reference Handler(RUNNABLE,daemon) Finalizer(WAITING,daemon) Signal Dispatcher(RUNNABLE,daemon) Notification Thread(RUNNABLE,daemon) Common-Cleaner(WAITING,daemon) DestroyJavaVM(RUNNABLE) [jvmti] 事件计数:ClassPrepare 172,ThreadStart 5,GC 开始 9、GC 结束 9
#include <jvmti.h>
JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *vm, char *options, void *reserved) {
(*vm)->GetEnv(vm, (void **)&jvmti, JVMTI_VERSION_1_2);
jvmtiCapabilities caps = {0}; caps.can_tag_objects = 1; caps.can_generate_garbage_collection_events = 1;
(*jvmti)->AddCapabilities(jvmti, &caps); // 申请能力
cb.GarbageCollectionStart = cbGCStart; cb.ClassPrepare = cbClassPrepare; cb.VMDeath = cbVMDeath;
(*jvmti)->SetEventCallbacks(jvmti, &cb, sizeof cb); // 注册回调
(*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, JVMTI_EVENT_CLASS_PREPARE, NULL); // 打开事件
return JNI_OK; }