JVM核心之类加载器
类加载器的作用
将class字节码加载到内存,并将这些静态数据转换成方法区中的运行时数据结构,同时在堆中生成一个该类的java.lang.Class对象,用于访问方法区中的运行时数据结构。
类缓存
一旦某个类被加载到类加载器,它将维持加载一段时间,这也就是类缓存。若没有缓存机制,同一个类每次主动引用时都需要重新加载,太消耗时间和资源。
*JVM垃圾回收器可以回收这些Class对象。
类加载器层次结构
- 启动类加载器:用来加载Java核心库(JAVA_HOME/jre/ext/rt.jar),用原生代码实现(C++),并不继承自java.lang.ClassLoader。
- 扩展类加载器:用来加载Java扩展库(JAVA_HOME/jre/ext/*.jar),用Java代码实现,继承自java.lang.ClassLoader。
- 应用程序类加载器:根据Java应用的类路径加载类,一般来说Java应用的类都是由它完成加载的,继承自java.lang.ClassLoader。
- 自定义类加载器:开发人员可以通过继承Java.lang.ClassLoader类的方式实现自己的类加载器,用于满足一些特殊的需求。
public class Demo01 { public static void main(String[] args) { System.out.println(ClassLoader.getSystemClassLoader()); System.out.println(ClassLoader.getSystemClassLoader().getParent()); System.out.println(ClassLoader.getSystemClassLoader().getParent().getParent()); } }
输出:
sun.misc.Launcher$AppClassLoader@18b4aac2//当前为应用程序类加载器 sun.misc.Launcher$ExtClassLoader@7f31245a//其父加载器为扩展类加载器 null//启动类加载器无法获取
java.lang.ClassLoader类
作用:根据一个指定类的名称,找到或者生成对应的.class字节码,然后通过这些字节码定义一个java.lang.Class类的实例
除此以外,ClassLoader还负责加载Java应用所需要的资源,如图像文件和配置文件等。
相关方法:
getParent() 返回该类加载器的父类加载器(启动类加载器无父类加载器)
loadClass(String name) 加载指定名称的类,返回结果为java.lang.Class类的实例
findClass(String name) 查找指定名称的类,若未加载则会加载该类,返回结果为java.lang.Class类的实例
findLoadClass(String name) 查找指定名称的已经被加载过的类,返回结果为java.lang.Class类的实例
defineClass(String name,byte[] b,int off,int len) 把字节数组b中的内容转换为Java类,返回结果为java.lang.Class类的实例
resolveClass<Class<?> class> 链接指定的Java类
类加载器的代理模式
当我们调用一个类加载器去加载一个类,当前的类加载器会交给其他类加载器去进行加载
双亲委托机制
其核心在于父类加载器优先加载,举个例子:我们通过一个自定义类加载器A去加载一个类,A会交给其父类加载器ApplicationClassLoader,ApplicationClassLoader又再交给其ExtensionClassLoader,ExtensionClassLoader又交给BootStrapClassLoader。BootStrapClassLoader负责加载核心库,加载失败交给子类加载器;ExtensionClassLoader负责加载扩展库,加载失败交给子类加载器;最后可能由ApplicationClassLoader或A进行加载,若直到加载器A都加载失败的话,则报错。
这种机制的优点是:可以很安全的去加载相关的类,避免加载用户自己定义的java.lang.Object类。
例如我自己定义了一个java.lang.String类,调用类加载器加载时,优先交给BootStrapClassLoader,而在BootStrapClassLoader中检查到核心类库中存在已经加载好的String类,则不会再加载,一定程度上防止了危险代码的植入。
双亲委托机制是保证Java安全的核心机制,也是代理模式的一种
但并不是所有的类加载器都采用双亲委托机制,tomcat服务器类加载器也使用代理模式,不同的是它首先尝试去加载某个类,如果加载失败再代理给父类加载器。
- 【JVM】JVM之类加载器
- JVM之类加载器
- 46、JVM之类加载器
- JVM 核心机制(类加载器、自定义文件系统类加载器、网络自定义类加载器
- 深入JVM之类的加载器
- JVM学习七:JVM之类加载器之类的卸载
- JVM学习四:JVM之类加载器之初始化分析
- JVM组成1 之类加载器(ClassLoader)
- JVM之类加载器(ClassLoader)基本介绍
- JVM学习三:JVM之类加载器之连接分析
- JVM学习二:JVM之类加载器之加载分析
- JVM学习五:JVM之类加载器之编译常量和主动使用
- JVM核心机制_深入类加载器JAVA220-223
- JVM学习一:JVM之类加载器概况
- Java虚拟机深入详解JVM之类加载器深度剖析、类的主动使用、被动使用
- jvm之类加载器(1)
- JVM原理之类加载器
- JVM核心机制_深入类加载器JAVA220-223
- JVM之类加载器
- JVM之类加载器