类加载机制

2018-10-18  本文已影响0人  冬冬269

1.一个类的生命周期。
1.加载
2.连接:验证、准备、解析
3.初始化
4.使用
5.卸载

有且仅有四种情况必须对类进行初始化:
1,new了一个实例对象 读取或设置类的静态变量 调用类的静态方法。
2.对类进行反射调用的时候。如果还没初始化必须先初始化。
3.当初始化一个类时,发现该类的父类还没有经过初始化。(接口除外)
4.当虚拟机启动时,用户需要指定一个要执行的主类。这个类初始化。

这四种场景成为对类的主动引用。被动引用:1.子类引用父类的静态变量,不会触发子类的初始化。2.数组引用。3.引用类中的静态常量。

类的加载过程。

1.加载(loading)(查找并添加类的二进制数据)

2.验证(确保被加载类的正确性)(记忆方法格式》类》方法》引用)

3.准备(在方法区中为类变量分配内存,并赋初始值)注意两点:

4.解析(把类中的符号引用转换为直接引用)
虚拟机将常量池内的符号引用替换为直接引用的过程。
个人理解
符号引用:符号引用是一组符号来描述所引用的目标对象,符号可以是任何形式的字面量,只要使用时能无歧义地定位到目标即可。符号引用与虚拟机实现的内存布局无关,引用的目标对象并不一定已经加载到内存中。
直接引用:直接引用可以是直接指向目标对象的指针(指向类变量,类方法)、相对偏移量(实例的变量)或是一个能间接定位到目标的句柄。直接引用是与虚拟机内存布局实现相关的,同一个符号引用在不同的虚拟机实例上翻译出来的直接引用一般不会相同,如果有了直接引用,那引用的目标必定已经在内存中存在

5.初始化(为类的静态变量赋予正确的初始值)四种情况一定会触发初始化。

类加载器和双亲委派模型。

一个类的唯一性是由加载它的类加载器和这个类的class文件一起确定的。

1.启动类加载器,由c++语言实现,是虚拟机自身的一部分。Bootstrap ClassLoader
2.剩余的类加载器都是继承自java.lang.ClassLoader类。

1.启动类加载器(Bootstrap ClassLoader):负责加载<JAVA_HOME>\lib 目录中的类
2.扩展类加载器(Extension ClassLoader ExtClassLoader):负责加载<JAVA_HOME>\lib\ext中的类。
3.应用程序类加载器(Application ClassLoader AppClassLoader):如果应用程序中没有自定义过自己的类加载器,一般情况下这个就是程序中默认的类加载器。

双亲委派模型:模型要求除了bootstrap classloader外,其余类加载器都应有自己的父类加载器,而这种父子关系一般通过组合关系来实现
工作过程;当一个类加载器收到加载类的请求时,首先不会自己尝试加载类,而是将该请求委托给自己的父类加载器,层层委托后,所有的请求都会委托到顶层的启动类加载器去加载,当父类加载器反馈自己无法加载时(它负责的范围内没有找到所需类),子类加载器才会尝试加载该类。
模型的优点:java类随着它的类加载器一起具备了一种带有优先级的层次关系。1.防止类被重复的加载。2.防止api核心类库中的类被篡改。

自定义一个类加载器。核心方法loadClass 和 findClass
是否要破环双亲委派模型。不破坏,只写findClass 破环 loadClass也重写。

热修复的两大主流方案:1.阿里系的底层替换方案。2.腾讯系的类加载方案。
底层替换方案:从底层C的二进制来解决问题,这样做限制颇多,但时效性最好,加载轻快,立即见效;
类加载方案:从Java加载机制来解决问题,这样做时效性差,需要重新冷启动才能见效,但修复范围广,限制少;

上一篇 下一篇

猜你喜欢

热点阅读