-
Parallel Scavenge收集器
-
Parallel Old收集器
-
CMS收集器
-
G1(重要)
-
理解GC日志
了解垃圾回收器
-
在垃圾回收器里主要做的俩件事就是: 标记(可达性分析) + 回收(标记清除 标记复制 标记整理 对象分代)
-
如何评价垃圾回收器的好坏
- 回收的效率 就是扫一遍 可以扫到多少垃圾
- 回收的速度 扫一遍要多长时间
- 垃圾回收和应用线程之间是否可以请发执行
- 垃圾回收器是否支持多线程
- 回收的时间是否是可以预测的 承诺10分钟一定扫完 即使扫的不是很干净 但是最大程度上把一些重要垃圾清理掉
- Java中Stop-The-World机制简称STW,是在执行垃圾收集算法时,Java应用程序的其他所有线程都被挂起(除了垃圾收集帮助器之外)。Java中一种全局暂停现象,全局停顿,所有Java代码停止,native代码可以执行,但不能与JVM交互;所以这些现象多半是由于GC引起。
Serial收集器
-
历史最悠久的收集器
-
给新生代使用 串行回收 使用复制算法 是单线程进行标记+回收
ParNew收集器
-
给新生代使用 支持多线程进行GC(并行)
-
回收效率比Serial高
Parallel Scavenge收集器
-
给新生代使用 支持多线程进行GC(并行)
-
设计初衷是为了尽量缩短STW的时间 但是这个是以牺牲吞吐量和新生代空间作为代价的 , 相当于承诺用户 在一定时间内就会完成一次GC虽然我删除的不是很干净 但是能够很大程度上清除大部分垃圾了
Parallel Old收集器
-
老年代收集器 支持多线程执行(并行)
-
ParNew的老年版本
-
这个收集器使用的是标记整理算法 效率更高 但是消耗的CPU资源更多
CMS收集器
-
老年代收集器 支持多线程并行 采用标记-清除
-
特点: 尽肯能缩短STW的时间
a: 初始标记 [STW]
只是把GCRoot直相关的对象先标记起来
b: 并发标记 [耗时 但不涉及STW]
执行整个遍历过程 从GCRoot开始 把所有访问到的对象都遍历一遍 不需要暂停用户线程 虽然耗时但是可以和用户线程并发 并发标记完成后得到的垃圾结果可能就和真实效果存在一定的误差
c: 重新标记 [STW]
修改刚才的误差 由于刚才误差的必经是少数 重新标记代价不是很大 虽然STW了 但是时间很小了
d: 并发清除 [耗时 但不涉及STW]
多线程的方式吧刚才的对象都释放掉 直接清除 当然也可以和应用线程并发执行
-
优点: 能够让STW时间尽量缩短
-
缺点: 内存碎片 应用线程是并发执行的 很消耗cpu的资源
G1(重要)
-
比较新的回收器 Java11开始默认使用的回收器
-
算是最优秀的垃圾回收器
-
老少通吃 既可以回收新生代 也能回收老年代
每一个矩形区域称为一个"region"
E代表伊甸区 S代表生存区 T代表老年代 H表示放大对象的区域
G1代回收的时候不一定需要一次性把整个内存都会收完 而是以region为单位进行回收(回收的粒度更加精细)
针对新生代的region同样是使用复制算法进行回收
针对老年代的回收类似CMS 但还是有一定差距
a: 初始标记
和CMS很类似 只去找GCRoot之间关联的对象 时间较短 会涉及STW
b: 并发标记
可并发, 进行可达性分析 遍历所有对象不涉及STW 和CMS不同的就是 如果发现老年代region已经没有对象存活 就之间回收 不等最后一个环节回收了
c: 最终标记