JVM的垃圾回收机制
主要的垃圾回收算法
引用计数法
- 增加引用+1,失去引用-1,只要任何一个对象引用了A,A的计数器就加1,以此类推
- 有两个严重的问题
- 无法处理循环引用的情况,会产生内存泄漏
- +1 -1会对系统性能有一定的影响
标记清除算法
- 是现代垃圾回收算法的思想基础
- 分两个阶段,标记阶段和清除阶段
- 缺点就是会产生空间碎片的问题
复制算法
- 将内存分为两块,每次只使用一块内存
- GC时将存活的内存复制到另外一快内存里,然后把第一块里面的对象都清除掉
- 有点事效率高,缺点是每次只能用一半的内存
- JVM中对复制算法的应用
- 分为新生代和老年代
- 新生代分为Eden,survive from和survive to ,每次GC都将Eden和sf里面存活的对象放到st里面,然后将sf和st转换位置
- 什么对象放到老年代
- BigObject
- Oldobject 15次GC之后还存活的
- 空间不足的时候
标记压缩算法
- 标记存活的对象,像一端移动,然后清理所有存活对象之外的空间
- 优点是不会产生空间碎片,也不会将内存一分为二,一般用于老年代,性价比比较高
分代算法
分区算法
- 将堆空间划分为连续的小空间
- 每个空间独立使用回收
- 可以控制每次回收多少个小空间,减少gc所产生的的停顿
JVM垃圾收集器
串行垃圾回收器
- 只使用单线程进行GC
- 独占式的GC ->stw stop the world
- shi JVM Client模式下默认的垃圾收集器
- 新生代用复制算法 老年代用压缩标记算法
CMS 并行垃圾回收器(将串行回收器多线程化)
- 初始标记 STW 标记根对象
- 并发标记所有的对象
- 预清理
- 重新标记
- 并发清理 标记遗漏的对象
- 并发重置
G1的GC收集过程
- 优先回收垃圾比例最高的区域,G1收集器将堆划分为多个区域,每次收集部分区域来减少GC产生的停顿时间
- 全代负责 新生代老年代
新生代GC
并发标记周期
- 初始标记 STW 标记根节点
- 根区域扫描 在survive区域里面标记可以存到老年代的对象
- 并发标记 标记整个堆存活的对象
- 重新标记 STW 最后的标记的阶段
- 独占清理 STW 计算每个区块存活对象和死亡对象的比例
- 并发清理 清理完全空闲的区域
混合收集
- 将垃圾比例比较高的区域清理,将剩余存活对象移动到其他区域,减少内存碎片
Full GC(不是必须)