类加载系统

目录

类加载过程

加载

链接

初始化

类加载器

BootstrapClassLoader

ExtClassLoader

AppClassLoader

类加载器间的关系

双亲委派机制

概述

优点

类加载过程

加载

通过完全限定名获取字节码数据流,将其加载进内存

链接

  • 验证:字节码格式等数据是否正确
  • 准备:静态变量分配内存,并赋值为对应数据类型的默认值
  • 解析:类中指向常量池的符号引用转为直接引用

初始化

静态变量显示赋值,执行静态代码块

类加载器

BootstrapClassLoader

C 语言实现,JVM 启动时创建该类加载器,属于 JVM 的一部分,加载 <JAVA_HOME>/lib 下的核心类

ExtClassLoader

是 sun.misc.Launcher 类中的一个静态内部类,加载 <JAVA_HOME>/lib/ext 下的类

java 复制代码
package sun.misc;

public class Launcher {

    // 扩展类加载器
    static class ExtClassLoader extends URLClassLoader {
        
    }
}

AppClassLoader

是 sun.misc.Launcher 类中的一个静态内部类,加载 classpath 类路径下的类

java 复制代码
package sun.misc;

public class Launcher {

    // 应用程序类加载器
    static class AppClassLoader extends URLClassLoader {
        
    }
}

类加载器间的关系

体现在 sun.misc.Launcher 类的构造方法,BootstrapClassLoader 作为 ExtClassLoader 的父加载器,ExtClassLoader 作为 AppClassLoader 的父加载器

java 复制代码
package sun.misc;

public class Launcher {
    
    public Launcher() {
        ExtClassLoader var1;
        try {
            // 创建ExtClassLoader,将其parent属性设置为null(BootstrapClassLoader并非Java语言编写)
            var1 = Launcher.ExtClassLoader.getExtClassLoader();
        } catch (IOException var10) {
            throw new InternalError("Could not create extension class loader", var10);
        }

        try {
            // 创建AppClassLoader,并将它的parent属性设置为ExtClassLoader
            this.loader = Launcher.AppClassLoader.getAppClassLoader(var1);
        } catch (IOException var9) {
            throw new InternalError("Could not create application class loader", var9);
        }

        // 设置AppClassLoader为线程上下文类加载器
        Thread.currentThread().setContextClassLoader(this.loader);

    }
    
}

双亲委派机制

体现在 java.lang.ClassLoader 类中的 loadClass 方法

概述

当某个类加载器加载某个类时,首先调用 native 本地方法 findLoadedClass0 方法检查该类是否已经被加载,已经被加载就直接返回,若没有被加载,则调用 parent 父类加载器的 loadClass 方法将类加载任务交给父类加载器,当到 ExtClassLoader,将类加载任务给 BootstrapClassLoader,不在父类加载器的加载范围加载不了,则类加载任务再由子类加载器加载

java 复制代码
package java.lang;

public abstract class ClassLoader {

    public Class<?> loadClass(String name) throws ClassNotFoundException {
        return loadClass(name, false);
    }

    protected Class<?> loadClass(String name, boolean resolve)
        throws ClassNotFoundException
    {
        synchronized (getClassLoadingLock(name)) {
            // First, check if the class has already been loaded
            // 先检查该类是否已经被加载过
            Class<?> c = findLoadedClass(name);
            if (c == null) {
                long t0 = System.nanoTime();
                try {
                    // 该类未被加载
                    if (parent != null) {
                        // 如果其parent父类加载器不为空,则调用父类加载器的loadClass方法
                        c = parent.loadClass(name, false);
                    } else {
                        // parent父加载器为null,则当前类加载器为ExtClassLoader,则交给BootstrapClassLoader
                        c = findBootstrapClassOrNull(name);
                    }
                } catch (ClassNotFoundException e) {
                    // ClassNotFoundException thrown if class not found
                    // from the non-null parent class loader
                }

                if (c == null) {
                    // If still not found, then invoke findClass in order
                    // to find the class.
                    long t1 = System.nanoTime();
                    c = findClass(name);

                    // this is the defining class loader; record the stats
                    sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
                    sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
                    sun.misc.PerfCounter.getFindClasses().increment();
                }
            }
            if (resolve) {
                resolveClass(c);
            }
            return c;
        }
    }

}

优点

  • 防止同一个类被不同的类加载器重复加载
  • 提高安全性,防止 Java 核心类被篡改
相关推荐
用户094248568034 小时前
第23章:OpenJDK逃逸分析、标量替换与锁优化
java·jvm
wuminyu4 小时前
LockStack在虚拟线程Mount和Unmount拷贝过程剖析
java·linux·c语言·jvm·c++
2601_962071579 小时前
类变量和全局变量的隔离性有什么区别?
java·开发语言·jvm
估值探索者11 小时前
【Python量化系统工程实战 #01】数据存储选型 CSVSQLiteMySQL 对比与 SQLite 实战建库
开发语言·jvm·python·sqlite·api接口·数据api接口·股票数据api接口
打工仔折腾 AI1 天前
从 Demo 到生产级 Agent:8 个关键设计机制与 Python 实现拆解
java·jvm·人工智能·后端·python·langchain·ai agent 实战
用户094248568031 天前
第22章:JIT编译分层——Interpreter、C1、C2与热点探测
java·jvm
乌暮1 天前
JVM 原理与实践:从运行时数据区到线上故障排查
java·开发语言·jvm·后端·学习·面试
长河2 天前
Java的GC(垃圾回收)中,标记无用对象的核心方法是可达性分析算法
java·jvm·算法
可乐ea2 天前
GitHub Security Lab 开源 Fuzzing Taskflow:让 LLM 智能体自己跑完 C/C++ 模糊测试
jvm·c++·github·模糊测试·mcp·代码agent·智能体自动化
一条破秋裤2 天前
Linux 线程同步:读写锁
java·linux·jvm