类加载系统

目录

类加载过程

加载

链接

初始化

类加载器

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 核心类被篡改
相关推荐
一直不明飞行9 小时前
Java的equals(),hashCode()应该在什么时候重写
java·开发语言·jvm
2301_8039346110 小时前
Go语言如何做网络爬虫_Go语言爬虫开发教程【指南】
jvm·数据库·python
2301_8039346112 小时前
MySQL 字段类型选择规范指南
jvm·数据库·python
阿坤带你走近大数据14 小时前
Java中的JVM、类加载记住、多线程、性能优化的概念
java·jvm·性能优化
雪度娃娃16 小时前
转向现代C++——优先选用限定作用域的枚举型别,而非不限作用域的枚举型别
java·jvm·c++
欢璃18 小时前
笔试强训练习
java·开发语言·jvm·数据结构·算法·贪心算法·动态规划
Dicky-_-zhang18 小时前
Go语言内存管理与GC机制深度解析
java·jvm
老纪19 小时前
c++怎么利用std--variant处理多种二进制子协议包的自动分支解析【进阶】
jvm·数据库·python
JAVA面经实录91719 小时前
JVM高频面试总结(背诵完整版)
java·开发语言·jvm
沪漂阿龙19 小时前
Java JVM 面试题详解:JVM运行原理、内存模型、堆栈方法区、GC垃圾回收、JIT编译、类加载机制与线上调优全攻略
java·开发语言·jvm