程序员一代码搬运工
【Java学习心得和Java学习技术个人总结】

jvm中的classLoader的初步了解

Classloader 类加载器,用来加载Java类到 Java 虚拟机中的一种加载器。

jvm中的classLoader的初步了解

作用:

ClassLoader的具体作用就是将class文件加载到jvm虚拟机

注:

隐式加载:不通过在代码里调用ClassLoader来加载需要的类,而是通过JVM来自动加载需要的类到内存,例如:当类中继承或者引用某个类时,JVM在解析当前这个类不在内存中时,就会自动将这些类加载到内存中。

显示加载:在代码中通过ClassLoader类来加载一个类,例如调用this.getClass.getClassLoader().loadClass()或者Class.forName()。

前提:

java程序并不是一个可执行的文件,

而是由多个独立的类文件组成的,

每个文件对应一个java类

此外,这些文件并非全部装入内存,而是根据程序需要逐渐载入

Java语言系统自带有三个类加载器:

Bootstrap ClassLoader:最顶层的加载类,主要加载核心类库,%JRE_HOME%lib下的rt.jar、resources.jar、charsets.jar和class等;

Extention ClassLoader:扩展的类加载器,加载目录%JRE_HOME%libext目录下的jar包和class文件;

Appclass Loader:也称为SystemAppClass,加载当前应用的classpath的所有类;

AppClassLoader的父加载器是ExtClassLoader,而ExtClassLoader的父加载器是BootstrapClassLoader。

注:父加载器不是父类,不能通过getParent()判定。

jvm中的classLoader的初步了解

全盘负责 是指当一个ClassLoader装载一个类时,除非显示地使用另一个ClassLoader,则该类所依赖及引用的类也由这个CladdLoader载入。

双亲委托

JVM加载一个class时先查看是否已经加载过,没有则通过父加载器,然后递归下去,直到BootstrapClassLoader,如果BootstrapClassloader找到了,直接返回,如果没有找到,则一级一级返回(查看规定加载路径),最后到达自身去查找这些对象。

“双亲委派”机制:真正加载class字节码文件生成Class对象

1. 源ClassLoader先判断该Class是否已加载,如果已加载,则返回Class对象;如果没有则委托给父类加载器。

2. 父类加载器判断是否加载过该Class,如果已加载,则返回Class对象;如果没有则委托给祖父类加载器。

3. 依此类推,直到始祖类加载器(BootstrapClassLoader)。

4. 始祖类加载器判断是否加载过该Class,如果已加载,则返回Class对象;如果没有则尝试从其对应的类路径下寻找class字节码文件并载入。如果载入成功,则返回Class对象;如果载入失败,则委托给始祖类加载器的子类加载器。

5. 始祖类加载器的子类加载器尝试从其对应的类路径下寻找class字节码文件并载入。如果载入成功,则返回Class对象;如果载入失败,则委托给始祖类加载器的孙类加载器。

6. 依此类推,直到源ClassLoader。

好处是:

  1. 避免重复加载
  2. A和B都需要加载X,各自加载就会导致X加载了两次,JVM中出现两份X的字节码;
  3. 防止恶意加载
  4. 编写恶意类java.lang.Object,自定义加载替换系统原生类;

常见的例子:Class.getResource()是通过委托给ClassLoader的getResource()

jvm中的classLoader的初步了解

JVM在判定两个class是否相同时,不仅要判断两个类名是否相同,而且要判断是否由同一个类加载器实例加载的。只有两者同时满足的情况下,JVM才认为这两个class是相同的。就算两个class是同一份class字节码,如果被两个不同的ClassLoader实例所加载,JVM也会认为它们是两个不同class。

当需要自定义classLoader

如下列情况:

  1. 我们需要的类不一定存放在已经设置好的classPath下(有系统类加载器AppClassLoader加载的路径),对于自定义路径中的class类文件的加载,我们需要自己的ClassLoader
  2. 有时我们不一定是从类文件中读取类,可能是从网络的输入流中读取类,这就需要做一些加密和解密操作,这就需要自己实现加载类的逻辑,当然其他的特殊处理也同样适用。
  3. 可以定义类的实现机制,实现类的热部署,如OSGi中的bundle模块就是通过实现自己的ClassLoader实现的。

其他classLoader下具体方法等有遇到在详细记录,这次只是初步了解下

未经允许不得转载:程序员一代码搬运工 » jvm中的classLoader的初步了解

分享到:更多 ()