一、垃圾判断方法
1.引用计数法
给对象添加一个引用计数器,当对象增加一个引用时计数器加 1,引用失效时计数器减 1。引用计数为 0 的对象可被回收
2.可达性分析算法
通过 GC Roots 作为起始点进行搜索,能够到达到的对象都是存活的,不可达的对象可被回收
一般可作为 GC Roots 的对象有:
(1)虚拟机栈中引用的对象
(2)本地方法栈中引用的对象
(3)方法区中类静态属性引用的对象
(4)方法区中的常量引用的对象
二、垃圾回收算法
1.标记-清除 速度快,但是会产生内存碎片
先根据可达性算法标记出可回收的对象,然后回收标记的对象
2.标记-整理 解决了内存碎片问题,但是每次都需要移动对象,成本高
3.复制 不需要移动对象,但是导致空间浪费
4.分代收集
将堆内存分为新生代(采用复制算法)和老年代(使用 标记 - 清除 或者 标记 - 整理 算法)
三、垃圾收集器
1.新生代 使用复制回收算法
(1)Serial
单线程,适合于Client模式下的虚拟机
(2)ParNew
Serial收集器的多线程版本,垃圾收集更快,能有效减少STW(Stop The World,在 GC(minor GC 或 Full GC)期间,只有垃圾回收器线程在工作,其他工作线程则被挂起)时间,提升应用的响应速度,主要工作在Server模式。除了Serial收集器,只有它能跟CMS收集器配合工作
(3)Parallel Scavenge
多线程,目标是达到一个可控制的吞吐量(运行用户代码时间 / 运行用户代码时间+垃圾收集时间),适合做后台运算等不需要太多用户交互的任务
2.老年代
(1)Serial Old
单线程,使用标记整理算法,适合于Client模式下的虚拟机
(2)Parallel Old
多线程,使用标记整理算法,真正实现了“吞吐量优先”的目标
(3)CMS 以实现最短STW为目标,采用标记清除算法
分为以下4个流程:
a.初始标记
仅标记 GC Roots 能关联的对象,速度很快,需要停顿
b.并发标记
进行 GC Roots Tracing 的过程,在整个回收过程中耗时最长,无需停顿
c.重新标记
修正并发标记期间因用户线程继续运行而导致标记产生变动的那一部分对象的标记记录,停顿时间一般比初始标记阶段稍长,但远比并发标记时间短
d.并发清除
标记清除,无需停顿
3.同时在新生代和老年代 G1
面向Server端的收集器,分为以下4个流程:
a.初始标记
b.并发标记
c.最终标记
修正并发标记期间因用户线程继续运行而导致标记产生变动的那一部分对象的标记记录,虚拟机将这段时间对象变化记录在线程的Remebered Set Logs中,此阶段需要把Remebered Set Logs的数据合并到Remebered Set,需要STW
d.筛选回收
通过引入 Region 的概念,从而将原来的一整块内存空间划分成多个的小空间,使得每个小空间可以单独进行垃圾回收。对各个Region中的回收价值和成本进行排序,根据用户所期望的GC停顿时间来指定回收计划,再把需要回收的Region中存活的对象复制到空的Region,同时清理掉旧的Region,需要STW