深入Java虚拟机读书笔记——第7章 类型的生命周期

第七章 类型的生命周期

 

1.       类型装载、链接与初始化

深入Java虚拟机读书笔记——第7章 类型的生命周期

 

装载:将二进制形式的Java类型读入Java虚拟机中;

连接:将二进制形式的类型数据合并到迅即的运行时状态中去;

A.    验证:确保Java类型数据格式正确并且适用于Java虚拟机适用;

B.    准备:负责为该类型分配它所需的内存环境;(如类变量分配内存)

C.    解析:负责将常量池中的符号应用转换为直接引用;

初始化:给类变量赋予适当的初始值;

                   JVM严格定义了初始化的时机,所有的Java虚拟机实现必须在每个类或者接口的首次主动使用时初始化:

1.       当创建这个类的新实例时(或者通过字节码执行new指令,或者反射,克隆,反序列化)

2.       调用某个类的静态方法

3.       使用这个类或者接口的静态字段,或者是对这个字段赋值(final修饰的字段除外,编译阶段被初始化为常量表)

4.       当调用Java API 中的某些反射方法时,比如Class中的方法或者java.lang.reflect包中的方法

5.       当初始化某个类的子类时;

6.       当标明为启动类时(含main方法的那个类)

被动使用:父类中声明的字段被子类引用,在子类中调用父类这个变量时,是不是初始化自己的;

 

1.       装载

3个基本动作:a 通过该类型的完全限定名,产生一个代表该类型的二进制数据流

                                   b 解析这个二进制数据流为方法区内的内部数据结构

                          c 创建一个表示该类型的java.lang.Class类的实例

2.       连接

验证: 确认类型符合Java语言的语义,并且他不会危及虚拟机的完整性(父类的装载(有的话),final的验证,符号引用的验证。。。)

准备: 为类变量分配内存空间,设置默认初始值

解析:将符号引用转化为直接引用的过程

 

3.       初始化:赋予正确的初始值

1)  如果类存在直接的超类,且还没有初始化的话,就先初始化超类(接口除外)

2)  如果类存在一个类初始化方法,就执行此方法

3)  初始化的过程是同步的

2.       对象的生命周期

1.       类的实例化:(4个方式,不多说了)

Java虚拟机创建一个类的新实例时,不管是明确的还是隐含的,首先都需要在堆中为保存对象的实例变量分配内存,所有在对象的类中它的超类中声明的变量都要分配内存。

2.       垃圾回收和对象的终结

程序可以明确或者隐含地位对象分配内存,但是不能明确地释放内存。如果类声明了一个名为finalize()的返回void的方法,垃圾收集器会在释放这个实例所占据的内存空间之前执行这个方法(被称为终结方法)一次。垃圾收集器最多只会调用一个对象的终结方法一次(在对象变成不再被引用的之后的某个时候,在占据的对象被重用之前)。

3.       卸载类型

使用启动类装载器装载的类型永远是可触及的,所以永远不会被卸载,只有使用用户自定义类装载器装载的类型才会变成不可触及的。
     
判断动态装载的类型Class实例在正常的垃圾收集过程中是否可以触及有两种方式,第一,也是最明显的,如果程序保持对Class实例的明确引用,它就是可触及的。其次,如果在堆中还存在一个触及的对象,在方法区中它的类型数据指向一个Class实例,那么这个Class实例就是可触及的。

你可能感兴趣的:(JAVA虚拟机)