垃圾回收算法
1. 标记-清除
- 过程:标记所有需要回收的对象,标记结束后,回收所有被标记的对象
- 缺点:效率低下,容易造成碎片
2. 复制
- 将内存空间分为两部分,每次只使用一部分,当一部分用尽,则将其所有对象复制到另一部分,并清理自身
- 特点:不产生碎片,但造成空间浪费
- 老年代将内存分为一个Eden 和两个Survivor,每次使用一个Eden 和一个Survivor,回收时,将存活的对象复制到另一个Survivor,当待复制对象大于另一个Survivor 时,老年代进行担保
3. 标记-整理
- 标记之后,将所有存活的对象移向另一端,清理其他对象
- 优点:解决了对象存活率高时,复制对象的压力
4. 分代收集
根据年轻代[ 1, 2]、老年代[ 3]各自的特点,采用不同回收算法
垃圾回收器
Serial
单线程,在进行GC 时,需要停止其他的所有线程
ParNew
Serial 的多线程版本。但是在单线程环境下,由于线程开销较大,效果不如Serial。但随着CPU 的增加,便可以显现出优势,默认线程数等于 CPU数。
Parallel Scavenge
多线程。可设置 1. 吞吐量(cpu 运行100分钟,GC 使用1分钟,Throughput = 99%),2. 最大GC 停顿时间(缩小GC 停顿时间,要以牺牲吞吐量和增加GC 频率为代价)
年轻代与老年代的分界线
Serial Old
Serial 的老年代版本
CMS
获取最短GC 停顿时间。基于标记-清除算法。
- 初始阶段:主要负责标记GC Root能直接关联的对象,速度快。
- 并发标记:从GC Root 开始继续向下标记,耗时。
- 重新标记:统计在并发标记过程中发生变化的标记,时间长于 初始阶段但小于 并发标记。
- 并发清除:清除老年代中的垃圾,耗时。
缺点:
- 产生碎片
- 浮动垃圾
- 对cpu 敏感
G1
可同时应用于年轻代和年老代的GC 器。基于标记-整理算法。使用时,堆内存布局发生变化,将堆分成性质不同的但大小相同的region,用以避免全局GC,建立可预测的停顿时间模型。每个 region对应一个 remembered set,当对象处于不同region,remember set 会进行记录,即可保证不进行全局GC,也不会遗漏。
- 初始标记
- 并发标记
- 最终标记:将并发标记过程中发生变化的对象写入线程remember set log,同时与remembered set 合并
- 筛选回收:通过比较region 的回收成本与价值,得到一个最好的回收方案
parallel old
老年代。标记-整理。吞吐量优先。
GC 时,程序逻辑是否继续执行?
Serial、parnew 等=> stop the world
CMS、G1 => 非并发阶段,程序逻辑继续执行。
标签:Java,标记,对象,回收,并发,GC,垃圾,Serial From: https://blog.51cto.com/u_11290086/5804051