JVM类加载机制和双亲委派模型

JVM类加载机制:

虚拟机把描述类的数据从 Class 文件加载到内存,并对数据进行效验、转换、解析和初始化,使其最终形成可以被虚拟机直接使用的 Java 类型的过程。

类的生命周期:

​ 类从被加载到虚拟机内存开始,到卸载出内存为止。类的整个生命周期可分为:**加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化(initialization)、使用(Using)、和卸载(Unloading)**7个阶段。

一、类加载过程

加载(获取来自任意来源的字节流,并将其转换成方法区运行时的数据结构,生成Class对象)。
验证(保证字节流信息符合当前虚拟机的要求,防止被篡改过的字节码危害虚拟机的安全)。
准备(为类变量【static修饰的变量】分配内存并设置初始值,若被final修饰,则设置为final指定的值)。
解析(将常量池的符号引用替换为直接引用,符号引用是用一组符号来描述所引用的目标,直接引用是指向目标的指针、相对偏移量和可间接定位到目标的句柄)。
初始化(执行类构造器、类变量赋值、静态语句块)。

二、初始化时机

1、时机
遇到 new、getstatic、putstatic、invokestatic 指令时,如new一个对象及静态字段/方法被使用的场景。
使用java.lang.reflect包对类进行反射调用时。
如果被初始化的类的父类没有被初始化,先初始化父类。
程序执行入口,即执行main()方法时,main() 方法所在的类需要先初始化。
使用动态语言支持时(JDK1.7及以后),如java.lang.invoke.MethodHandle实例最后的解析结果为:REF_getStatic、REF_putStatic、REF_invokeStatic的方法句柄,若这些方法句柄所对应的类还未初始化,需先触发其初始化。
总结:以上5种情况称为对一个类的主动引用,除此之外都是被动引用。主动引用时若类还未初始化过,则需先触发其初始化。

2、细节
引用一个类的静态字段,只有直接定义这个字段的类才会触发初始化。

通过定义一个类的数组来引用该类,不会触发该类的初始化。

引用一个类的常量不会触发该类的初始化。

常量在编译阶段会直接存入调用(者)类的常量池中,本质上没有引用到定义该常量的类,故不会触发其初始化。

三、类加载器

启动类加载器(BootStrap ClassLoader):

​ 用C++语言实现,是虚拟机自身的一部分,它负责加载 <JAVA_HOME>/lib路径下的核心类库(如rt.jar),无法被Java程序直接引用。

扩展类加载器(Extension ClassLoader):

​ 用Java语言实现,它负责加载<JAVA_HOME>/lib/ext目录下或者由系统变量-Djava.ext.dir指定位路径中的类库,开发者可直接使用该类加载器。

应用程序/系统类加载器(Application ClassLoader):

​ 用Java语言实现,它负责加载用户类路径ClassPath上指定的类库,开发者可直接使用该类加载器。

四、双亲委派模型

定义:

​ 每个类加载器在收到类加载请求时,都不会自己先加载,而是将该请求委派给父类加载器去完成,若父类加载器可以完成该类的加载请求任务,就成功返回,若父类加载器无法完成此加载任务,子加载器才会尝试自己去加载,这就是双亲委派模式。

优点:

​ 采用双亲委派模式可使Java类随着它的类加载器一起具备了一种带有优先级的层次关系,通过这种层级关系可以避免类的重复加载,当父加载器已经加载了该类时,就没有必要让子ClassLoader再加载一次。其次还可以防止子类加载器加载的类恶意覆盖Java核心API

三次大型破坏双亲委派模式的事件:

JDK1.2时,为类加载器添加了findClass()方法。因为在双亲委派模式出来之前,用户继承ClassLoader就是为了重写loadClass()方法,但双亲委派模式需要这个方法,所以它不能被用户随意重写。

Java团队添加了一个线程上下文加载器,为了解决基础类要调回用户的代码的问题。如JNDI/JDBC需要调用ClassPath下用户的代码来进行资源管理,如果该加载器没有被设置过,那么就默认是应用程序类加载器【applicationClassLoad】。线程上下文加载器的作用:可让父类加载器请求子类加载器去完成类加载的动作,这显然是违背了双亲委派的准则。

为了实现代码热替换。OSGi为了实现自己的类加载逻辑,用平级查找的逻辑替换掉了双亲委派模式向下传递的逻辑。但其实可以不破坏双亲委派逻辑而是自定义类加载器来达到代码热替换。

发布了126 篇原创文章 · 获赞 46 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/loulanyue_/article/details/100127373