类加载系统

目录

类加载过程

加载

链接

初始化

类加载器

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 核心类被篡改
相关推荐
万年咸鱼35 分钟前
JVM 内存区域详解
jvm
Escalating_xu3 小时前
【System V 信号量】从 P/V 原语到 Builder 封装:写出可控、可清理的进程互斥组件
java·linux·开发语言·jvm
HEJOO96 小时前
JVM 参数调优实战指南
jvm
码农哈丁8 小时前
从 JVM 到 Cargo:把整个 Kotlin 项目移植到 Rust 的踩坑实录
jvm·rust·kotlin
User_芊芊君子10 小时前
sbt 鸿蒙 PC 适配全记录:从 JVM 构建工具到 HAP_HNP 交付闭环
jvm·华为·harmonyos
小范的技术工坊10 小时前
每日一题gogogo
jvm
天空之城--1 天前
Flutter Drift 完全指南:从原理到实战
jvm·flutter·oracle
xiaohua10091 天前
JVM内存优化-jemalloc
java·jvm
Escalating_xu1 天前
【mmap 进程间通信】从共享内存到跨进程唤醒:用互斥锁、条件变量控制多个进程
java·linux·开发语言·jvm
雪落漂泊1 天前
C++智能指针
开发语言·jvm·c++