深入理解Java类加载机制

【深入理解Java原理】Java类加载机制

 

                                        Java类加载机制

所谓类加载机制是指 Java 虚拟机如何加载class文件?

类加载机制

虚拟机将类的数据从Class文件加载到内存,并对数据进行校验,转换解析,和初始化最终形成Java虚拟机可以使用的Java类型

                      

类从被加载到虚拟机内存开始,到卸载出内存为止,整个生命周期包括:

  • 加载(Loading)

 取得类的二进制流, jar,或者网络,java.lang.对象

  •    验证

   类 是不是正常的文件格式,oxCAFEBASE

   版本号是否合理

  • 元数据验证

         是否有父类

        是否final类

       抽象方式是否实现了所有的抽象方法

  • 字节码验证

 运行检查

  •  准备 

   分配内存

  • 解析
  • 初始化

JVM里的有几种classloader,为什么会有多种?

深入理解Java类加载机制_第1张图片

BootStrapClassLoader  JAVA_HOME/LIb

Extension  ClassLoader JAVA_HOME/lib/ext

Application  ClassLoader   CLASSPTAH 指定的路径

什么是双亲委派机制?介绍一些运作过程,双亲委派模型的好处?

深入理解Java类加载机制_第2张图片

工作机制

1.加载当前类时,判断当前类是否加载过,如果加载过,那么直接返回原来加载的类

2.当前ClassLoader 没有找到加载的类,委托父类加载器取加载,父类加载器同样先从缓存中去加载,然后委托父类去加载

双亲委派原则有什么好处?

主要是为了安全,因为 JVM 中区分不同类,不仅仅是根据类名,相同的 class 文件被不同的 ClassLoader 加载就是不同的两个类,如果相互转型的话会抛java.lang.ClassCaseException.

什么情况下我们需要破坏双亲委派模型?

深入理解Java类加载机制_第3张图片

Tomcat 为什么要这样设计 类加载机制?

1. 一个web容器可能需要部署两个应用程序,不同的应用程序可能会依赖同一个第三方类库的不同版本,不能要求同一个类库在同一个服务器只有一份,因此要保证每个应用程序的类库都是独立的,保证相互隔离。 

所以需要 webApp ClassLoader

2. 部署在同一个web容器中相同的类库相同的版本可以共享。否则,如果服务器有10个应用程序,那么要有10份相同的类库加载进虚拟机,这是扯淡的。 

 需要share ClassLoader 类加载器
3. web容器也有自己依赖的类库,不能于应用程序的类库混淆。基于安全考虑,应该让容器的类库和程序的类库隔离开来。 

 所以需要 catalina ClassLoader 类加载机制 Tomcat容器私有的类加载器,加载路径中的class对于Webapp不可见;


4. web容器要支持jsp的修改,我们知道,jsp 文件最终也是要编译成class文件才能在虚拟机中运行,但程序运行后修改jsp已经是司空见惯的事情,否则要你何用? 所以,web容器需要支持 jsp 修改后不用重启。

tomcat 是支持JSP 热部署的 ,jsp 文件其实也就是class文件,那么如果修改了,但类名还是一样,类加载器会直接取方法区中已经存在的,修改后的jsp是不会重新加载的。那么怎么办呢?我们可以直接卸载掉这jsp文件的类加载器,所以你应该想到了,每个jsp文件对应一个唯一的类加载器,当一个jsp文件修改了,就直接卸载这个jsp类加载器。重新创建类加载器,重新加载jsp文件, 所以会需要一个JSP classLoader 

  • commonLoader:Tomcat最基本的类加载器,加载路径中的class可以被Tomcat容器本身以及各个Webapp访问;
  • catalinaLoader:Tomcat容器私有的类加载器,加载路径中的class对于Webapp不可见;
  • sharedLoader:各个Webapp共享的类加载器,加载路径中的class对于所有Webapp可见,但是对于Tomcat容器不可见;
  • WebappClassLoader:各个Webapp私有的类加载器,加载路径中的class只对当前Webapp可见;

最后记得给我点个关注哦,每天都会分享Java有关的文章

你可能感兴趣的:(Java虚拟机,类加载机制,程序员)