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

Posted 蓝风9

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了49 多个 classloader 加载的同类限定名的Class 在 jhat 中显示不全相关的知识,希望对你有一定的参考价值。

前言

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

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

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

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

大致记录一下 

以下内容, 截图 基于 jdk8 

测试用例 

/**
 * Test27MultiClassInClassloader
 *
 * @author Jerry.X.He <970655147@qq.com>
 * @version 1.0
 * @date 2021-12-12 14:27
 */
public class Test27MultiClassInClassloader 

    // Test27MultiClassInClassloader
    public static void main(String[] args) throws Exception 

        List<Object> refs = new ArrayList<>();
        ClassLoader appClassloader = Test27MultiClassInClassloader.class.getClassLoader();
        URL[] classpath = new URL[]
                new File("/Users/jerry/IdeaProjects/HelloWorld/target/classes").toURI().toURL()
        ;
        String[] alwaysParentPattern = new String[];
        for (int i = 0; i < 10; i++) 
            ChildFirstClassLoader classLoader = new ChildFirstClassLoader(classpath, appClassloader, alwaysParentPattern);
            Class userClazz = classLoader.loadClass("com.hx.test12.Test27MultiClassInClassloaderUser");
            System.out.println(" the " + i + "th classloader " + Integer.toHexString(userClazz.hashCode()));
            Object userInstance = userClazz.newInstance();
            refs.add(userInstance);
        

        System.in.read();

    


运行时截图如下, 可以看到 多次 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, 记录一下而已 

完 

以上是关于49 多个 classloader 加载的同类限定名的Class 在 jhat 中显示不全的主要内容,如果未能解决你的问题,请参考以下文章

40 classpath中存在多个jar存在同限定名的class classloader会如何加载

40 classpath中存在多个jar存在同限定名的class classloader会如何加载

ClassLoader

ClassLoader 功能简介

类的加载classload

ClassLoad 类加载