1_JVM类加载机制
2022-10-07 13:48:55 0 举报
AI智能生成
JVM类加载机制脑图
作者其他创作
大纲/内容
JVM类加载过程
类运行过程
MyMath类运行过程如图所示。当执行java MyMath时,java.exe回调用底层jvm.dll创建Java虚拟机和引导类加载器实例,然后调用java代码创建JVM启动器实例,该实例中会创建扩展类加载器和应用类加载器。然后启动器实例获取应用类加载器实例使用loadClass加载类,加载完成后,找到main方法入口,C++会发起调用,main方法执行完后,JVM销毁。其中loadClass过程(将类加载进虚拟机)和JVM的类加载器是需要重点了解。
类加载过程
JVM一般是懒加载的,即当程序真正去使用一个类时,类加载器加载该类到虚拟机中,而不是一启动就将路径下所有的类都加载进来,所以在程序运行过程中,loadClass会经常被调用去加载class文件进入虚拟机,下面来看下loadClass里面具体都做了什么
loadClass()过程
loadClass中采用了双亲委派机制,最终使用findClass加载类,类完整的加载过程需要经过加载、验证、准备、解析、初始化、使用、卸载七个阶段,前五个阶段并非是前一个阶段执行完成,才能执行后一个阶段,中间可能是交织进行的。
加载:将class文本文件转化为二进制字节流,加载进JVM中,加载过程中会生成一个Class对象,作为这个类各种数据的访问入口
真正加载之前涉及双亲委派机制,决定使用哪个类加载器加载该类
真正加载之前涉及双亲委派机制,决定使用哪个类加载器加载该类
验证:验证字节流是否符合JVM虚拟机规范
准备:为类中定义的静态变量分配内存和赋初始值,final变量直接赋值
解析:将类中常量池内的符号引用替换为直接引用,javap -v MyMath.class
初始化:给静态变量赋值,并执行静态代码块。(实例变量内存分配和赋初值,使用到的时候,现在仅仅是加载类)
类加载器
类加载需要依赖类加载器来完成,JVM启动时,会产生三个类加载器,分别是引导类加载器、扩展类加载器、应用类加载器。其中扩展类加载器、应用类加载器,是在getLauncher()时候创建的,且将其父类加载器关系构造好。
JVM基于安全考虑(防止核心类库被随意修改、防止重复加载),设计出三种类加载器分别加载不同的类库,要实现这三个类加载器分别加载自己的类库,就有了双亲委派机制。
JVM基于安全考虑(防止核心类库被随意修改、防止重复加载),设计出三种类加载器分别加载不同的类库,要实现这三个类加载器分别加载自己的类库,就有了双亲委派机制。
引导类加载器
加载/JAVA_HOME/lib目录下的类库
扩展类加载器
加载/JAVA_HOME/lib/ext目录下类库
应用类加载器
加载用户类路径下类库
双亲委派机制
当使用应用类加载器loadClass加载类时,首先判断当前类是否已经被加载,有则直接返回;没有则调用父类加载器(非父类)加载,一直到引导类加载器,若引导类加载器未找到类且加载该类失败,则调用扩展类加载器的findClass完成类加载,如果加载不到则继续调用子类加载器findClass完成类加载如果还加载不到就报错。
双亲委派机制
全盘负责委托机制
当一个类加载器装加载一个类时,除非显式的使用另一个类加载器,否则该类依赖和引用的其他类也由这个加载器加载
自定义类加载器
为什么有了以上三个类加载器,我们还需要自定义类加载器呢?
需要加载的jar不在类路径下,可能咋在网络上或者其他地方
代码加密
一个tomcat启多个应用,每个应用依赖同一个jar包的不同版本
需要加载的jar不在类路径下,可能咋在网络上或者其他地方
代码加密
一个tomcat启多个应用,每个应用依赖同一个jar包的不同版本
1、继承ClassLoader
2、重写findClass()
2、重写findClass()
打破双亲委派机制
为什么要打破双亲委派机制
一个tomcat启多个应用,每个应用依赖同一个jar包的不同版本,如果不打破双亲委派的话,一个java类只允许加载一次,应用无法正常启动
JDBC
JDBC
如何打破双亲委派机制
打破双亲委派:只要加载的类不是按照应用->扩展类->启动类,就算是打破了
1、继承ClassLoader
2、重写loadClass
2、重写loadClass
Tomcat打破双亲委派机制
tomcat给每个web应用创建一个类加载实例WebAppClassLoader,这个类中重写了loadClass方法,让其先加载当前应用目录下的类,如果找不到才向上委托。对于多个WEB可以共用的类,就可以放在同一目录下,让SharedClassLoader去加载。
Jsp热加载:Jsp类加载器,每个JSP文件就有一个类加载器,有一个线程,监听文件修改,然后清空当前类加载器,赋值新的classLoader
JDK7之后Common、Catalina和shared合并成了一个,都使用同一个类加载器加载
Jsp热加载:Jsp类加载器,每个JSP文件就有一个类加载器,有一个线程,监听文件修改,然后清空当前类加载器,赋值新的classLoader
JDK7之后Common、Catalina和shared合并成了一个,都使用同一个类加载器加载
模拟tomcat打破双亲委派机制
算法题
爬楼梯
超时:f(n) = f(n-1) + f(n-2)
优化:使用变量记录f(n-1)和f(n-2)的结果
0 条评论
下一页
为你推荐
查看更多