【问题标题】:How IBM JVM classloaders hold classes?IBM JVM 类加载器如何保存类?
【发布时间】:2012-12-19 06:46:06
【问题描述】:

在 HotSpot JVM 中,java.lang.Classloader 类具有由该类加载器加载的所有类的 Vector。因此,只要类加载器还活着,所有类都保存在内存中。在 IBM JVM J9 的 java.lang.Classloader 中没有这样的字段。至少我找不到一个。所以我的问题是:

  1. IBM JVM 的类加载器在哪里保存类缓存?

  2. 如果与上述不同:IBM JVM 中有哪些硬引用类,从而阻止卸载?

【问题讨论】:

    标签: java memory-leaks jvm classloader


    【解决方案1】:

    看我的 IBM JVM 的代码,java.lang.ClassLoader 似乎是一个抽象类,所以它会在某个地方实现。使用调试器,我发现这是一个名为 sun.misc.Launcher$AppClassLoader 的合成类。
    然后,检索一个类有一个本地方法
    private native Class findLoadedClassImpl(String className);
    所以看起来缓存是在 Java 之外以本机方法完成的。

    loadClass 方法的开头我看到了:

    // Ask the VM to look in its cache.
    Class loadedClass = findLoadedClass(className);
    

    然后它检查loadedClass 是否为空,如果是则尝试使用父类加载器。
    所以,我想说的是,除非该方法被继承的类加载器覆盖,否则缓存发生在 Java 之外,在 IBM VM 的某些本机组件中。

    【讨论】:

    • 不幸的是,这并没有解决我的问题:(而且你的答案也不是 IBM JVM 特定的。Hotspot 的行为方式相同,只是它暴露了类缓存。J9 没有。
    • 你的问题是什么?需要看什么是类缓存吗?
    • 其实我有两个问题。一个更容易通过解决方法解决:查找此特定类加载器加载了哪些类。第二个有点困难:找出谁硬引用了给定的类,从而防止它们被 GC。
    • 我认为使用默认的类加载器是不可能的,可能是为了让 JVM 在不同的 JVM 进程之间管理类publib.boulder.ibm.com/infocenter/java7sdk/v7r0/topic/…(作为一个疯狂的猜测,我认为它在应用程序服务器中用于缓解permgen 大小问题),因此通常您不应该能够访问此缓存,因为要实现自己的缓存机制,您可以实现自己的类加载器。
    • 嗯,第一部分可以使用java.lang.instrument.Instrumentation来实现,所以这是完全可能的。
    【解决方案2】:

    IBM J9 JVM 在堆上没有 PermGen,并将类存储在本机内存中。您可以使用 -Xdump 生成一个 javacore.* 文件,它将包含所有类加载器和类的列表。

    顺便说一句:Java8 会做类似的事情。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-12
      • 2016-12-06
      • 2011-11-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多