首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >未准备的JVMTI类

未准备的JVMTI类
EN

Stack Overflow用户
提问于 2021-12-05 15:28:30
回答 1查看 195关注 0票数 2

我正在使用JVMTI编写一个本机Java代理,它将遍历所有加载类的所有方法。不幸的是,许多类似乎还没有准备好,因此GetClassMethods返回JVMTI_ERROR_CLASS_NOT_PREPARED。我正在注册一个ClassPrepare事件回调,但这似乎只在很少的类中调用。简化(减去所有错误处理和取消分配)我的代码如下所示

代码语言:javascript
复制
JNIEXPORT jint JNICALL Agent_OnAttach(JavaVM* jvm, char *options, void *reserved) {

     jvmtiEnv *jvmti;
     jint class_count;
     jclass* classes;
     jint method_count;
     jmethodID* methods;

     (*jvm)->GetEnv(jvm, (void**) &jvmti, JVMTI_VERSION_11);
     (*jvmti)->GetLoadedClasses(jvmti, &class_count, &classes);
     for (int i = 0; i < class_count; i++) {
       jclass klass = classes[i];
       // here a lot of time JVMTI_ERROR_CLASS_NOT_PREPARED is returned
       jvmtiError err = (*jvmti)->GetClassMethods(jvmti, klass, &method_count, &methods);
     }

使用JCMD和JVMTI.agent_load命令动态地将代理附加到正在运行的JVM上。我确实尝试注册了一个类准备回调,使用:

代码语言:javascript
复制
jvmtiEventCallbacks callbacks;
(void)memset(&callbacks, 0, sizeof(callbacks));
callbacks.ClassPrepare = &callbackClassPrepare;
(*jvmti)->SetEventCallbacks(jvmti, &callbacks, (jint) sizeof(callbacks));
(*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, JVMTI_EVENT_CLASS_PREPARE, (jthread) NULL);

但这只会被要求上极少数的课程。

如何让JVM准备加载的类,以便GetClassMethods返回JVMTI_ERROR_NONE

到目前为止,我只使用JDK 17.0.1和神南多阿GC进行了测试。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-12-08 23:41:10

当某些类加载而不是连系时,这是一种正常的情况。您不需要做任何手工准备类的事情-- JVM在需要时会自动地这样做。JVM规范保证类在初始化之前就已经完全准备好了。一旦发生,JVM TI ClassPrepare事件就会被触发。

因此,为了获得所有可用的jmethodID,您需要:

  1. 迭代所有加载的类,忽略可能的JVMTI_ERROR_CLASS_NOT_PREPARED
  2. 设置ClassPrepare事件回调并在其中调用GetClassMethods
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70235772

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档