类加载系统

目录

类加载过程

加载

链接

初始化

类加载器

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 核心类被篡改
相关推荐
南极企鹅5 小时前
JVM-编译执行过程
jvm
苏克贝塔9 小时前
.NET开发之.net framework对比.net core
jvm
cfm_291411 小时前
JVM垃圾收集算法与收集器深度解析
jvm·测试工具·算法·性能优化
自律懒人13 小时前
AI Agent 工作流编排实战:从单 Agent 到多 Agent,手搭一套能跑通的协作系统
jvm
石一峰69914 小时前
SQLite 与 db_manager 集成关键概念详解
jvm·数据库·sqlite
布朗克1681 天前
34 JVM深入理解
java·jvm
eggrall1 天前
Linux线程:并发编程的双刃剑
jvm
程序员晨曦1 天前
深入浅出JVM内存结构
jvm·面试·职场和发展
cfm_29142 天前
JVM对象创建与内存分配机制深度解析
jvm
wuminyu2 天前
Java锁膨胀机制之偏向锁到轻量级锁源码剖析
java·linux·c语言·jvm·c++