如何确定垃圾
引用计数法
一个对象如果没有任何与之关联的引用,即他们的引用计数都不为0,则说明对象不太可能被用到,那么这个对象就是可回收对象
可达性算法
通过一系列GC Roots对象作为起点搜索。如果在GC roots和一个对象之间没有可达路径,则称该对象是不可达的。不可达对象变为可回收对象至少要经过两次标记过程。
四种GC算法
标记清除法 Mark Sweep
标记阶段标记处所有需要回收的对象,清除阶段回收被标记的对象所占用的空间
问题:内存碎片化严重,后续可能发生大对象不能找到可利用空间的问题
复制算法 Copying (大部分新生代都采用此方法,因为回收大部分对象,需要复制的少)
将内存划分成等大小的两块,每次只使用其中一块,当着一块内存满后将尚存活的对象复制到另一块上区,把已使用的内存清掉
问题:可用内存被压缩到了原本的一般,且存活对象多时效率低
标记整理算法 Mark Compact (老年代使用此方法,因为每次只回收少量对象)
标记后不是清理对象,而是将存活对象移向内存另一端,然后清除边界外对象
分代收集算法
不同代采用不同的算法
6种GC收集器
Serial垃圾收集器(单线程,复制算法)
单线程收集器,使用复制算法,只使用一个CPU或者一条线程,且在进行GC的同时,必须暂停其他工作直到收集结束。简单高效,对于限定CPU时,没有线程交互的开销
ParNew收集器 (多线程版Serial)
多线程版Serial,也使用复制算法,默认开启和CPU相同数目的线程
Parallel Scavenge收集器 (多线程,复制算法)
关注重点是使程序达到一个可控制的吞吐量,以最高效的利用CPU时间
Serial Old收集器 (单线程,标记整理)
使serial的老年代版,采用标记整理算法
Parallel Old收集器 (多线程,标记整理)
Parallel Scavenge的老年代版,采用标记整理算法
CMS收集器 Concurrent Mark Sweep (多线程,标记清除)
主要目的是获取最短垃圾回收停顿时间,分为四个阶段
初始标记
只标记GC Roots能直接关联的对象,速度很快,但需要暂停所有工作线程
并发标记
进行GC Roots跟踪过程,不需要暂停工作线程
重新标记
修正在并发期间,因继续运行产生标记变动的对象,此时要暂停工作线程
并发清除
清除GC Roots不可达对象,不需要暂停工作线程
G1收集器 Garbage First
- 基于标记整理,不产生内存碎片
- 精准控制停顿时间,实现低停顿垃圾回收
- 避免全区垃圾收集,把堆内存划分成大小固定独立区域,同时在后台维护一个优先等级表,每次根据允许收集的实现,优先收集垃圾最多的区域
- 有限时间内有最高的回收效率