JVM类加载

心已入冬 提交于 2020-03-03 07:55:19

类加载机制

类从被加载到虚拟机内存开始,到卸载出内初为止,它的整个生命周期:加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)和卸载(Unloading)7个阶段。其中验证、准备、解析3个部分统称为链接(Linking)
JVM类加载
初始化:5种情况
1,遇到new、getstatic、putstatic和invokestatic这4个字节码指令时,如果类没有进行过初始化,则需要先触发其初始化
2,使用java.lang.reflect包的方法对类进行反射调用
3,当初始化一个类,如果发现其父类没有进行过初始化,则需要先触发其父类的初始化。
4,当虚拟机启动时,需要启动一个主类,虚拟机先初始化其主类
5,当使用JDK1.7的动态语言支持时,如果一个java.lang.invoke.MethodHandle实例最后解析结果Ref_getStatic、REF_getStatic、REF_putStatic、REF_invokeStatic的方法句柄,这个方法对应类没有初始化,则需先进行初始化。

加载阶段:
1,通过一个类的全限定名来获取定义此类的二进制自己流
2,将静态存储结构转换为方法区运行时数据结构
3,再内存中生成一个java.lang.Class对象,作为方法区这个类的各种数据的访问入口

验证:确保Class文件字节流符合当前虚拟机要求
准备阶段:正式为类分配内存并设置类的出事阶段
解析阶段:虚拟机常量池内的符号引用替换为直接饮用的过程

类加载器

对于任意一个类,都需要由加载它的类加载器和这个类本身一同确立其在java虚拟机中的唯一性,每个类加载器都拥有独立的类名称空间。
对任意一个类来说,确定它的唯一性:类的全限定名+类加载器。

加解密:通过位的二进制异或运算进行加解密(一次就是加密,再运算一次就是解密)。自定义一个类加载器,继承ClassLoader,同时在加载时尽心个解密。

双亲委派模型

JVM类加载
对于任意一个类,都需要由加载它的类加载器和这个类本身一同确定其在java虚拟机中的唯一性。
java虚拟机角度只有两种类加载器
1, 启动类加载器:这个类加载器使用C++实现,是虚拟机自身的一部分。
2,扩展类加载器:这个类加载器由sun.misc.Launcher$ExtClassLoader实现,开发者可以直接使用扩展类加载器
JVM类加载
应用程序类加载器:ClassLoader中loadClass方法中的代码逻辑就是双亲委派模型。自定义ClassLoader的子类时,常见两种方法:
1,一种是重写loadClass方法
2,重写findClass方法
两种方法本质上差不多,毕竟loadClass也会调用findClass,不建议修改loadClass内部逻辑,所以建议findClass里重写自定义加载器。

通俗理解双亲委派模型 ---> 重写类加载过程中,会向上级一层一层的询问,如果上级加载了,就不会再加载了。

Tocmat类加载机制

Tomcat本身就是一个java项目,因此也需要被JDK的类加载器加载,也就必然存在引导类加载器、扩展类加载器和应用(系统)类加载器。

JVM类加载
隔离应用:Tomcat打破双亲委派。new出来多个WebApp ClassLoader来实现多个项目同时运行,实现隔离。

当Tomcat启动时,需要创建集中类加载器:
1,Bootstrap引导类加载器:加载JVM启动所需类,以及标准扩展类(位于jre/lib/ext下)
2,System系统类加载器:加载Tomcat启动类,通常在catalina.bat或catalina.sh中指定。位于CATALINA_HOME/bin
3,Common通用类加载器:加载Tomcat使用以及应用通用的一些类
4,webapp应用类加载器:每个应用在部署后,都会常见一个唯一的类加载器。多个war包相互隔离,可以同时部署多个项目。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!