1:jvm遇到new :首先判断是否别类加载器加载,然后class 加载到 jvm内存数据区
类加载
检查加载:检查这个指令参数是否可以在常量池中有对应类的符号引用,并检查是否被加载/解析/初始化
分配内存 -》指针碰撞 (适合内存规整)/ 空闲列表(适合内存不规整)
并发情况下 cas加失败重试/本地线程分配缓冲(tlab)
内存空间初始化:比如Integer 0
设置 给对象头赋值
对象初始化 --这块是程序员做的
2 对象
对象头 存储运行时的数据 哈希码
gc年龄
类型指针
数组长度
实例数据
对齐填充
3 对象的定位
句柄(间接引用):
直接指针
4 判断对象的存活,或者说是不是垃圾:
1)引用计数法,但无法处理循环应用
2) 可达性分析:
5 可达性分析
判断对象的存活,从Gcroot 开始,从这些节点开始向下搜索,走过的节点叫引用链。当一个对象到Gcroot没有任何引用链则证明对象不可用
6 常见的Gcroot
1 虚拟机栈中引用的对象,各个现场被调用方法区堆栈的使用的变量
2 方法区中静态类引用的对象,
3 方法区中常量引用的对象
4 本地方法栈中的jni引用的对象
7 finalize 方法
可以给要被gc的对象第二次机会去寻找他的引用对象,但是优先级极低
8 各种引用
强 =
软 softReference 一般用于缓存,oom时会被回收
弱 weakReference 只能活到下次gc前
虚 phantomReference (幽灵引用) 监控gc是否正常
9 逃逸分析
是否会被其他方法调用,如果不会逃逸到线程之外,那么会把它放到栈上,可以提高jvm效率
10 对象的分配策略
优先eden区,如果是大对象则直接进入老年代,如果对象的年龄大于15就会晋升到老年代
11 空间分配担保
如果老年代连续空间总和是否大于新生代所有对象总和
如果大于,那么进行minorGc
如果不大于,看是否设置允许担保失败
如果允许,看老年代是否存在连续空间大于晋升老年代对象大小,
如果不允许进行fullGc
如果大于,进行minorGc
否则 fullGc
12 对象分配策略图
new
是否分配到栈上
本地线程分配缓冲
是否大对象 大 老年代
小 eden