JVM01_堆内存分配和回收机制(16)
年轻代
Eden满了之后淘汰没有用的对象,如果没有引用指向它就是垃圾对象,如果eden满的时候jvm产生一个操作叫垃圾回收操作叫ygc、ygc只会产生在eden区满的时候,产生ygc的时候应用程序是停止工作的。
ygc做两件事:
① 寻根判断(判断对象哪些是引用的哪些是没有引用的进行分别做标记)知道谁是垃圾对象谁不是垃圾对象
② 把存活的对象移动到s0或者s1区里。非存活对象直接在堆里干掉。Eden里就空了。
③ 清理ygc的时候应用程序是暂停的状态。
④ 清理之后可以放对象了、如果又满了产生ygc把存活的放到s1里、s0里的存活也要放到s1里,s0里空了(s0、s1两个存活区大小相当位置互换这时可以互换,就是说一直有一个存活区是空的)。
⑤ 判断s0和s1是否都满了,如果都满了就去老年代。
ygc和fgc的区别:
① ygc对eden区和两个存活区垃圾回收,内存小、标记时间短、回收快。
② fgc对整个堆和非堆垃圾回收。
老年代
① 大对象直接进入老年代,因为比较大放到年轻代就得一直启动ygc所以直接放到老年代。
② 长期存活的对象进入老年代、jvm有个参数控制产生ygc的次数(age默认15次如果这个对象在eden存活16次一直没有被销毁,就说明这个是长期存活对象,直接进入老年代)
③ 对象的动态分配原则s0和s1满了之后判断age对象。从age=1开始,存活区里相同的age对象大小之和是否大于存活区的一半大小,如果是下次ygc时候会把大于等于age放到老年代里。
对象 a b c d e f h i j k m l n
1 3 3 2 10 9 8 5 4 3 1 2 12
计算存活区里age对象的值,计算age里所有相同对象之和,例如:age =1 那就是a+m是否大于存活区的一半,放入老年代区域,如果age=1不满足,就计算age=2,d+l之和是否大于存活区的一半对象放到老年代里。