• 49 多个 classloader 加载的同类限定名的Class 在 jhat 中显示不全


    前言

    呵呵 这是在之前 排查一个 flink 的相关问题的时候 发现的一个问题 

    flink 默认的 job 隔离是基于 Classloader 来进行隔离的 

    直到 最近才有时间来看一下 

    这个问题的原因, 究其代码 也还是比较容易找到 

    大致记录一下 

    以下内容, 截图 基于 jdk8 

    测试用例 

    1. /**
    2. * Test27MultiClassInClassloader
    3. *
    4. * @author Jerry.X.He <970655147@qq.com>
    5. * @version 1.0
    6. * @date 2021-12-12 14:27
    7. */
    8. public class Test27MultiClassInClassloader {
    9. // Test27MultiClassInClassloader
    10. public static void main(String[] args) throws Exception {
    11. List<Object> refs = new ArrayList<>();
    12. ClassLoader appClassloader = Test27MultiClassInClassloader.class.getClassLoader();
    13. URL[] classpath = new URL[]{
    14. new File("/Users/jerry/IdeaProjects/HelloWorld/target/classes").toURI().toURL()
    15. };
    16. String[] alwaysParentPattern = new String[]{};
    17. for (int i = 0; i < 10; i++) {
    18. ChildFirstClassLoader classLoader = new ChildFirstClassLoader(classpath, appClassloader, alwaysParentPattern);
    19. Class userClazz = classLoader.loadClass("com.hx.test12.Test27MultiClassInClassloaderUser");
    20. System.out.println(" the " + i + "th classloader " + Integer.toHexString(userClazz.hashCode()));
    21. Object userInstance = userClazz.newInstance();
    22. refs.add(userInstance);
    23. }
    24. System.in.read();
    25. }
    26. }

    运行时截图如下, 可以看到 多次 loadClass, 拿到的 java.lang.Class 分别是不同的 class, 会对应于多个 InstanceKlass, 多个 java.lang.Class 

    保存一下 dump 文件, 然后使用 jhat 分析一下 

    查询所有的 Class, 搜索一下 Test27MultiClassInClassloaderUser 只能搜索到一个 

    并且只有一个 instance, 那么 其余九个 Test27MultiClassInClassloaderUser.class, 以及其对应的 instance 呢? 

    问题的调试 

    问题在于 jhat, showInstanceCounts/includePlatform 的处理基于读取出来的 dump 对应的 snapshot.classes 

    然后我们看一下 解析的时候, 这个 classes 的存储 

    是根据 全限定名 来作为 key 的, 因此 多个 classloader 加载的同一个 class 会被覆盖 

    可以看到这里有一个 name, 如果是存在 多个相同的全限定名的情况下, 有一个额外的处理, 但是 为什么 最终传递给 classes 的还是 c.name 这个就不得而知了, 可能是存在一些更大的影响 

    我们这里暂且使用 putInClassMap 中的 name 作为 key 来试试 

    呵呵 小 case, 记录一下而已 

    完 

  • 相关阅读:
    Go语言Web开发入门指南
    十五、C++11常用新特性—Lambda表达式
    PDFBOX和ASPOSE.PDF
    前端工具宝库,帮你解决99%的业务需求难题
    四只股票的收盘价可视化
    Android 14适配记录
    如何面向对象编程?程序员:我也要先有“对象”啊
    用Unity实现Flat Shading
    React进阶
    华为appgallery上架
  • 原文地址:https://blog.csdn.net/u011039332/article/details/121887423