垃圾回收
什么是垃圾:
没有对象引用的就是垃圾 (= .=)
红色部分由于没有对象引用,此时可以认为它是一坨垃圾
如何找到垃圾:
1.引用计数
有一次引用,那么我们就将该对象引用次数+1.当引用数为0时,表明没有对象引用。
无法解决循环引用的问题
循环依赖,没有被外部引用。实质上他们已经是一堆垃圾了。
2.根可达算法
什么是根对象:
线程栈对象、静态变量、常量池、JNI指针(C/C++本地方法用的变量)
常用的垃圾回收算法:
1、标记清除(mark-sweep)
适合存活对象比较多,需要清除的对象比较少,扫描两次
缺点:会产生大量的内存碎片
2、拷贝(copying)
它将可用内存按容量划分为大小相等的两块,每次只使用其中的一块,当这一块的内存用完了,就将还存活着的对象复制到另外一块上面,然后再把已使用过的内存空间一次清理掉。
适用于存活对象比较少,只扫描一次。没有内存碎片(伊甸区)
缺点:
1、对象引用需要调整
2、将可使用内存降低了一半
3、标记压缩(mark-compact)
标记整理其中的标记过程仍然与标记清除算法一样,但后续步骤不是直接对可回收对象进行清理,而是让所有存活的对象都向内存空间一端移动,然后直接清理掉边界以外的内存,如下图所示。
缺点:
1、对象引用需要调整
2、扫描两次
JVM内存分代模型
1.部分垃圾回收器使用的模型
ZGC/Shenandoah之外的GC都是使用逻辑分代模型
G1是逻辑分代,物理不分代
2.新生代+老年代+永久代(1.7)PermGeneration / 元数据区(1.8) MetaSpace
- 永久代 元数据 -Class
- 永久代必须指定大小限制,且确定后不可以修改。元数据可以设置,也可以不设置,无上限
- 字符串常量 1.7-永久代 1.8 -堆
- MethodArea 是逻辑概念 - 永久代、元数据是具体实现
可以通过参数改变分代模型的比例
对象什么时候进入老年代
大对象直接进入老年代
-XX:MaxTenuringThreshold 指定次数(YGC)
- Parallen Scavenge 15
- CMS 6
- G1 15
动态年龄:
- Hotspot遍历所有对象时,按照年龄从小到大对其所占用的大小进行累积,当累积的某个年龄大小超过了survivor区的一半时,取这个年龄和MaxTenuringThreshold中更小的一个值,作为新的晋升年龄阈值。
常见垃圾回收器
1.Serial
a stop-the-world,copying collector which uses a single GC thread
单线程收集器、收集垃圾时,会停止其他任务执行,采用复制算法
2.Serial Old
a stop-the-world,mark-sweep-compact collector that uses a single GC thread
单线程,采用标记清除/压缩算法
3.Parallel Scavenge
a stop-the-world,copying collector which uses multiple GC threads
多线程收集器,复制算法
4.Parallel Old
a compacting collector that uses multiple GC threads
多线程收集器,压缩算法
5.Parallel New
a stop-the-world ,copying collector which uses multiple GC threads
// 与Parallel Scavenge 相比做了一些增强用于与CMS配合
It differs from “Parallel Scavenge” in that it has enhancements that make it usable with CMS
PN 响应时间优先
PS 吞吐量优先
6.CMS
1.4 后期引入,开启并发回收
concurrent mark sweep
a mostly concurrent,low-pause collector
4 phases
- initial mark(初始标记)
- concurrent mark(并发标记)
- remark(重新整理)
- concurrent sweep(并发清除)
CMS缺点:
- 内存碎片化(mark sweep) => 出现 无法进行升级时 会动用Serial Old 单线程进行清除
- 浮动垃圾
解决方案
=> 降低触发CMS的阈值:
=>保持老年代有足够的空间
- -XX:CMSInitiationgOccupancyFraction 92%
7.G1
1.9 默认
1.8 默认 PS + PO
模型改变=> 逻辑上区分新生代 老年代 物理上不区分
当需要GC时,收集存活对象最少的Region
并发收集
压缩空闲空间不会延长GC的暂停时间
适用不需要实现很高吞吐量的场景,需要快的响应时间
G1回收:
YGC:Eden空间不足
FGC:Old空间不足
MixedGC(45%): GC过程相当于一个CMS. -XX:InitiationHeapOccupacyPercent,当超过阈值时, 启动MixedGC
如果产生FGC:
- 扩内存
- 提高CPU性能
- 降低MixedGC触发的阈值
8.ZGC
9.Shenandoah
并发标记阶段算法:
CMS:三色标记+ Incremental Update
G1: 三色标记+ SATB(snapshot at the begining)
三色标记:
漏标:
remark过程中
黑色对象指向白色对象
B对象没有指向 D ,
此时 由于A已经被标记完成,不会再进行遍历,此时D漏标
解决方案:
打破上述产生条件
1、incremental update --增量更新,关注引用增加,跟踪A指向D的引用,将黑色重新标注为灰色,下次重新扫描属性(CMS)
2、SATB (snapshot at the beginning) --关注引用删除,当B指向D消失时,把这个引用推到GC的堆栈,保证D还能被GC扫描到(G1)