JVM
2021-01-12 14:29:19 0 举报
jvm垃圾回收
作者其他创作
大纲/内容
survivor2区域是否够存放存活的对象
栈上分配
survivor1(10%)
lab_top + size <= tlab_end
是
对象创建在新生代分配内存eden(Eden区加锁,线程竞争)
存活的对象放入老年代
老年代剩余可用大小是否大于新生代整个区域大小
eden内存是否充足
eden区(80% 空间)
新生代GC复制算法
A
否
优先在栈上分配内存,栈帧出现即内存回收
垃圾回收器新生代:ParNew STW的时候并行回收,线程数和cpu核心相同老年代:CMS回收器 1.初始标记 标记从GC roots直接引用的对象 STW 速度快2.并发标记 可以同时创建新对象并。回收线程对老年代所有的对象进行GC roots追踪。找到GC root标记存活 最耗时3.重新标记 重新标记在第二阶段变动的对象 STW 速度很快4.标记清理 在程序运行的同时清理标记的对象 并行 耗时很长5.当CMS在并发垃圾回收的时候(老年代比例触发CMS回收 92%-jdk1.6默认,-XX:CMSInitiatingOccupancyFaction),如果新生代产生新对象引发minor gc后存活的对象在老年代不够分配,那么JVM会用serial Old垃圾回收器替代CMS,STW后进行垃圾回收
是否是大对象
full gc之后老年代是否够存放新生代存活对象
下一次minorGC会把eden和survivor1存活的对象复制到survivor2区域
fullGC回收老年代和新生代
对象A两个成员变量fieldB=null fieldC=Cspan style=\"font-size: inherit;\
还存活的对象会被迁移到survivor区域
是否动态年龄判断对象大小超过survivor一半的内存区域的最大年龄
新生代
AfieldB fieldC
触发minor GC
full GC
CMS并发标记 3色标记法黑色 被GC root 引用,且当前对象以及他的成员变量均完成标记不是垃圾灰色 当前对象完成标记不是垃圾(成员变量没有)白色 没有标记产生漏标问题的条件有两个:1.黑色对象指向了白色对象(被引用对象回收 有问题)2.灰色对象指向白色对象的引用消失(下一轮会被回收)跟踪黑指向白的增加incremental update:增量更新,关注引用的增加,把黑色重新标记为灰色,下次重新扫描属性。CMS采用该方法。记录灰指向白的消失SATB snapshot at the beginning:关注引用的删除,当灰–>白消失时,要把这个 引用 推到GC的堆栈,保证白还能被GC扫描到。G1采用该方法。
对象创建首先判断是否符合在栈分配
C
-XX:CMSInitiatingOccupancyFaction CMS内存回收比率92%触发垃圾回收
-XX:PretenureSizeThreshold
存活对象存放老年代
开始
是否设置-XX:-HandlePromotionFailure
编译器通过逃逸分析,确定对象是在栈上分配还是在堆上分配
老年代剩余可用大小是否大于之前minorGC存活对象的平均大小
GC root
oom异常
老年代是否够存放存活的对象
存放老年代
B
survivor2(10%)
新对象创建还是会在eden区分配,此时新生代在使用的是eden和一个survivor区域
dk1.5+默认的单个线程是占用1M的内存
标记整理算法
新生代进入老年代的条件1.年龄太大,超过jvm设置的默认15次gc还存活的对象2.动态年龄判断,超过survior的50%,如果年龄1+年龄2+年龄3>50%,那么年龄3以上的进入老年代3.minorGc后存活的兑现survior放不下直接进入老年代4.大对象,超过jvm设置的大对象大小,直接进入老年代
对象不在堆上分配主要的原因还是堆是共享的,在堆上分配有锁的开销。无论是TLAB还是栈都是线程私有的,私有即避免了竞争(当然也可能产生额外的问题例如可见性问题),这是典型的用空间换效率的做法。TLAB空间的内存非常小,缺省情况下仅占有整个Eden空间(GC的年轻代空间——GC快)的1%
重新申请一个TLAB,并再次尝试存放当前对象
直接在TLAB分配对象并增加tlab_top 的值
-XX:MaxTenuringThreshold
是否超过15岁
minor GC 和 full GC
0 条评论
下一页
为你推荐
查看更多