JVM内存型模:1.程序计数器2.Java虚拟机栈3.本地方法栈4.方法区 (JDK8在末使用区域另外开,元数据区)5.堆区6.运行时常量池,jdk6方法区的一部份 (JDK7,8回到堆中)《JVM常量池》7.直接内存
JAVA类的生命周期包括7个部分:加载——验证——准备——解析——初始化——使用——卸载
JAVA内存模型和类的生命周期紧密相连。
1.加载阶段
《类加载机制》一文,描述出类在加载阶段的时候,会用到 4.方法区 6.运行时常量池。
2.连接阶段及初始化
验证——准备——解析 称为连接阶段。
1.验证:确保class文件的二进制字节流中包含的信息符号虚拟机要求,包括:文件格式验证、元数据验证(数据语义分析)、字节码验证(数据流语义合法性)、符号引用验证(符号引用的匹配性校验,确保解析能正确执行)
2.准备:为类对象在堆区分配内存,并设置零值。注意:这里是类变量,不是实例变量。(下图的Sample类的Class对象)
3.解析:把常量池中的符号引用解析为直接引用:根据符号引用所作的描述,在内存中找到符合描述的目标并把目标指针指针返回。 例:图中#1 = class. //com.moyao.test.APP. 他只是字符串,而不真正的找到APP这类在内存中的地址。解析过程就是把字符引用换成 Sample类的Class对象真正内存地址。
为了加快系统的启动速度,往往会采用懒解析,用到什么再解析什么,ClassLoader类中有一个resolveClass 可以强行解析。
初始化:JVM在堆区创建了Sample类的Class对象,会为它初始化。具体初始化的东西,被 static修改的变量,static块中的的代码。他们会被编译器统一收集放到一个<cinit>的方法中。
此阶段,5.堆区慢慢的进入视野。
3.使用阶段
《JAVA运行栈》与 《JVM垃圾回收》两对对象的运行使用及管理做了较深入的说明。
《JAVA直接内存(堆外内存)》则是为一场特殊的场景提供了,脱离堆管理的办法。
此阶段,1.程序计数器2.Java虚拟机栈3.本地方法栈5.堆区7.直接内存
4.卸载阶段
《JAVA对象引用》一文,我知道怎么判断定一个对象是否死亡。更进一步上左图是对象在内存的分布图,将图中左侧三个引用变量都置为null,
- 1.Sample对象结束生命周期
- 2.MyClassLoader对象结束生命周期
- 3.代表Sample类的Class对象也结束生命周期
- 4.Sample类在方法区内的二进制数据被卸载
当再次有需要时,会检查Sample类的Class对象是否存在,如果存在会直接使用《类加载机制》,不再重新加载;如果不存在Sample类会被重新加载,在Java虚拟机的堆区会生成一个新的代表Sample类的Class实例(可以通过哈希码查看是否是同一个实例)。
此阶段,2.Java虚拟机栈3.本地方法栈4.方法区 5.堆区 6.运行时常量池,其中 2,3,6是可能作为GC,ROOT