指标
读完周志明老师《深刻了解Java虚拟机》之后,感觉须要将书读薄,将外面的常识死记硬背。所以以一个Class的生命周期作为角度重新整理常识,有一个残缺的认知。
生命周期
- 编译:将java源代码通过编译器编译成合乎class文件标准的二进制class文件。
- 加载:依照肯定的初始化的规定程序,进行加载、验证、筹备、解析和初始化的过程,将类加载到办法区,实现类的定义加载到虚拟机。
- 实例化:应用new命令进行实例化对象,依照之前加载的类进行分片空间,将对象调配到堆。
- 执行:依据命令执行执行,其中办法调用波及多态的抉择,波及程序计数器和虚拟机栈的应用。
- 收集:在命令的执行会产生很多对象散布在JVM内存中,会依据不同的策略进行收集。
编译
将java源码代码编译成合乎class文件标准的二进制class文件。而class文件的格局如下
ClassFile { u4 magic; u2 minor_version; u2 major_version; u2 constant_pool_count; cp_info constant_pool[constant_pool_count-1]; u2 access_flags; u2 this_class; u2 super_class; u2 interfaces_count; u2 interfaces[interfaces_count]; u2 fields_count; field_info fields[fields_count]; u2 methods_count; method_info methods[methods_count]; u2 attributes_count; attribute_info attributes[attributes_count];}
加载
将class文件依照初始化的触发条件通过类加载器进行加载。
初始化的条件
- 执行new 、getstatic、putstatci、invokestatic指令
- 反射调用
- 类存在父类,父类先初始化,接口不须要
- 启动须要执行的主类
- JDK7中,MethodHandle解析构造REF_getStatic、REF_putStatic、REF_invokeStatic
- JDK8中,定义接口的默认办法,如果实现类产生初始化,则接口先初始化
加载的生命周期
- 加载:将class文件加载到办法区和运行时常量池,存储类的常量池、字段和办法和一些非凡办法
链接
- 验证:验证class文件是否符合规范的文件
- 筹备:创立类或接口的动态变量,并且赋予默认值
- 解析:依据运行时常量池的符号援用决定具体的办法
- 初始化:初始化类变量和其余资源
解析的过程不肯定在筹备之后,也可能产生运行时进行解析,比方多态的应用
实例化
通过new命令进行实例化,实例化之后的对象不仅仅是定义的类的构造,也存在一些用于收集和并发管制的须要的信息,而后在堆内依照肯定的约定在不同的区域进行调配。
对象组成
对象头
- 哈希码
- GC分代年龄
- 锁状态标记
- 线程持有的锁
- 偏差线程ID
- 偏差工夫戳
- 类型指针
- 实例数据
- 对齐填充
对象存储地位
- 大多数对象间接调配到Eden区
- 大对象(须要大量间断内存)调配到Tenured区
- 对象在Survivor区熬过一次新生代GC年龄减少1,当减少到15,存储在老年代
- Survivor空间雷同年龄的所有对象大小总和大于Survivor的一半
执行
依据class文件解析之后的命令应用虚拟机栈和程序计数器进行执行,其中会存在办法多态的一个解析。
虚拟机栈组成
- 局部变量表:办法入参,局部变量
- 操作数栈:用于执行存储执行命令须要的参数
- 动静链接:指向运行时的常量池的援用
- 办法返回地址
收集
JVM中的内存不同区域会在不同的状况下会进行不同的收集。
收集堆
- Eden区空间不能进行调配会进行MinorGC,将存活的对象存储在Survivor区
- Survivor区对象年龄达到MaxTenuringThreshold值会存储在Tenured区
- Survivor区雷同年龄的所有对象大小总和大于Survivor区空间的一半,大于等于该年龄的对象进入Tenured区
- MinorGC进行空间调配担保,如果Tenured区的可用的间断空间小于降职Tenured区均匀大小,则进行FullGC,如果大于,同时HandlePromotionFailure为true,则进行冒险MinorGC,如果还是不够则进行FullGC
- Tenured区空间不够,会先进行MinorGC,如果空间还是有余则进行MajorGC
收集办法区
- 没有进行援用的常量,则收集
收集类型
- 该类下的所有实例曾经被回收
- 加载改类的类加载器被回收
- 类的class对象没有被援用