首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么JVM为同一个类发送多个JVMTI ClassLoad事件?

为什么JVM为同一个类发送多个JVMTI ClassLoad事件?
EN

Stack Overflow用户
提问于 2018-08-10 14:29:53
回答 1查看 196关注 0票数 0

我启用了JVMTI ClassLoad事件,这些事件应该在首次加载类时生成。我希望在加载的每个类中准确地得到这个事件一次,但是对于某些类,它似乎是多次生成的,例如,这个事件我得到了两次:

代码语言:javascript
复制
ClassLoad: Ljava/util/concurrent/ThreadFactory; loaded by thread 1
ClassLoad: Ljava/util/concurrent/ThreadFactory; loaded by thread 1

systemDictionary.cpp中,我发现了三个JvmtiExport::post_class_load,我认为它是负责执行回调(如果有的话)的代码。他们在

  1. SystemDictionary::resolve_instance_class_or_null
  2. SystemDictionary::parse_stream
  3. SystemDictionary::define_instance_class

但我还不明白整个流程,因此不清楚为什么我要多次得到这个事件。

我能做些什么来防止这种情况吗?还是我需要自己来处理,并调整代码以忽略同一个类的多个事件?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-08-19 18:46:41

看两次这个活动是可以的。这意味着类解析在不同的类加载器的上下文中发生两次。首先,它由引导类加载程序解析,然后由系统类加载器- sun.misc.Launcher.AppClassLoader解析。

this answer的实用程序将揭示此类事件发生时的情况。

考虑一个简单的例子:

代码语言:javascript
复制
public class Test {

    public void setThreadFactory(ThreadFactory factory) {
    }

    public static void main(String[] args) {
    }
}

当启动程序查找public static void main()时,它会为公共方法创建Method对象,这将导致解析这些方法签名中的所有类。

第一个ClassLoad事件:

代码语言:javascript
复制
Class loaded: java/util/concurrent/ThreadFactory
  - ClassLoad(_jvmtiEnv*, JNIEnv_*, _jobject*, _jclass*) + 0x69
  - JvmtiExport::post_class_load(JavaThread*, Klass*) + 0x15b
  - SystemDictionary::define_instance_class(instanceKlassHandle, Thread*) + 0x3cc
  - SystemDictionary::find_or_define_instance_class(Symbol*, Handle, instanceKlassHandle, Thread*) + 0x35d
  - SystemDictionary::load_instance_class(Symbol*, Handle, Thread*) + 0x20c
  - SystemDictionary::resolve_instance_class_or_null(Symbol*, Handle, Handle, Thread*) + 0x78c
  - JVM_FindClassFromBootLoader + 0x22b
  - Java_java_lang_ClassLoader_findBootstrapClass + 0x9b
  * java/lang/ClassLoader.findBootstrapClass @ -1
  * java/lang/ClassLoader.findBootstrapClassOrNull @ 12
  * java/lang/ClassLoader.loadClass @ 48
  * java/lang/ClassLoader.loadClass @ 38
  * sun/misc/Launcher$AppClassLoader.loadClass @ 81
  * java/lang/ClassLoader.loadClass @ 3
  * java/lang/Class.getDeclaredMethods0 @ -1
  * java/lang/Class.privateGetDeclaredMethods @ 37
  * java/lang/Class.privateGetMethodRecursive @ 2
  * java/lang/Class.getMethod0 @ 16
  * java/lang/Class.getMethod @ 13
  * sun/launcher/LauncherHelper.validateMainClass @ 12
  * sun/launcher/LauncherHelper.checkAndLoadMain @ 214

第二项:

代码语言:javascript
复制
Class loaded: java/util/concurrent/ThreadFactory
  - ClassLoad(_jvmtiEnv*, JNIEnv_*, _jobject*, _jclass*) + 0x69
  - JvmtiExport::post_class_load(JavaThread*, Klass*) + 0x15b
  - SystemDictionary::resolve_instance_class_or_null(Symbol*, Handle, Handle, Thread*) + 0x87c
  - SystemDictionary::resolve_or_fail(Symbol*, Handle, Handle, bool, Thread*) + 0x33
  - get_mirror_from_signature(methodHandle, SignatureStream*, Thread*) + 0xc6
  - Reflection::get_parameter_types(methodHandle, int, oopDesc**, Thread*) + 0x18e
  - Reflection::new_method(methodHandle, bool, bool, Thread*) + 0xfc
  - get_class_declared_methods_helper(JNIEnv_*, _jclass*, unsigned char, bool, Klass*, Thread*) + 0x479
  - JVM_GetClassDeclaredMethods + 0xcb
  * java/lang/Class.getDeclaredMethods0 @ -1
  * java/lang/Class.privateGetDeclaredMethods @ 37
  * java/lang/Class.privateGetMethodRecursive @ 2
  * java/lang/Class.getMethod0 @ 16
  * java/lang/Class.getMethod @ 13
  * sun/launcher/LauncherHelper.validateMainClass @ 12
  * sun/launcher/LauncherHelper.checkAndLoadMain @ 214
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51788702

复制
相关文章

相似问题

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