垃圾收集算法
- 标记-复制算法
将内存分成两块且相同大小,每次只使用一块,当该块内存使用满时,将存活的对象复制到另一块内存中。比较浪费内存, 优点是不会产生内存碎片。 - 标记-清除算法
- 由于需要收集的内存较大,存在效率问题
- 收集完垃圾后没有整理内存空间,会产生内存碎片
- 标记-整理算法
垃圾收集器
CMS收集器
收集过程
- 初始标记: 标记GC Roots根直接引用的对象, 会STW
- 并发标记: 从初始标记后的结果向下标记, 期间产生新对象会直接标记为黑色.
- 重新标记: 标记由并发标记阶段产生的漏标对象, 使用增量更新方式.
- 并发清理: 清理所有白色对象, 即垃圾对象. 期间产生新对象会直接标记为黑色.
- 并发重置: 清理对象的三色标记.
多标和漏标
并发标记阶段会产生多标和漏标的对象.
- 多标-浮动垃圾
- 由于存在用户线程, 会导致部分已经标记的局部变量被销毁变成浮动垃圾
- 由于存在用户线程, 产生的新对象也可能会变成浮动垃圾
- 漏标-读写屏障
- 三色标记
黑色: 所有直接引用都标记了的对象.
灰色: 至少存在一个引用未被标记的对象.
白色: 没有被扫描到的对象. - 增量更新算法
当对象引用发生改变时, 通过后置写屏障将该对象记录到队列中, 并将该对象设为灰色, 后续再从队列中取出对象进行重新标记。
相较与SATB会减少浮动垃圾, CMS垃圾收集器就是使用了该算法. - SATB算法
当对象引用删除时, 通过前置写屏障将原引用对象记录到队列中, 后续再进行重新标记。
- 三色标记
注:由于并发标记和并发清理存在用户线程,所以可能出现未GC完就又触发了FullGC,即concurrent mode failure
, 此时会进入STW并使用serial old来收集垃圾,且过程不可逆。
CMS核心参数
参数 | 作用 |
---|---|
-XX:+UseConcMarkSweepGC | 开启CMS |
-XX:ConcGCThreads | 设置GC并发线程数 |
-XX:+UseCMSCompactAtFullCollection | FullGC后做碎片整理 |
-XX:CMSFullGCsBeforeCompaction | 设置多少次FullGC之后整理一次碎片 |
-XX:CMSInitiatingOccupancyFraction | 设置老年代达到多少比例时触发FullGC |
-XX:+CMSScavengeBeforeRemark | 设置在FullGC前启动一次minor gc |
-XX:+CMSParallellnitialMarkEnabled | 开启初始标记时多线程执行 |
-XX:+CMSParallelRemarkEnabled | 开启重新标记时多线程执行 |
G1收集器
G1适用于多核且大内存的服务器
内部结构
上图中的每个小格子称为一个region, 每个region大小相等,且不超过2048个region(JVM默认将堆内存划分成2048个region)。
新生代初始(默认)占比为5%,会随着系统运行动态的进行分配,但是最多不超过60%。年轻代的内部结构还是和之前的垃圾收集器一样,存在E区和S区,且E:S0:S1=8:1:1
Humongous用于存储大对象,当对象大小大于E区的50%时,会直接放进H区。比如每个region大小为2M,新对象大小大于1M时就会放入H区。FullGC时会回收H区。
收集过程
- 初始标记(STW):同CMS的初始标记
- 并发标记:同CMS的并发标记
- 最终标记(STW):同CMS的重新标记
- 筛选回收(STW):根据设定的GC停顿时间(默认200ms)来制定回收计划,优先选择回收价值较大的region,最终计算出来需要回收的region称为
Collection set
。由于存在最大停顿时间,所以并不是每次GC都可以将所有垃圾都清理掉,未清掉的垃圾会在下一次FullGC再次清理。
从整体看,G1使用了"标记-整理"算法, 在回收region的时候采用的又是复制算法。所以G1几乎不存在内存碎片问题。
垃圾回收种类
- Young GC
E区放不下新对象时,G1会优先计算出回收当前E区所需时间,若远小于设定的停顿时间,G1会将对象放入新的E区,而不会触发GC。 - Mixed GC
当老年代占比达到设定的阈值触发。根据停顿时间,回收年轻代和部分老年代以及H区。 - Full GC
在Mixed GC回收过程中,如果没有多余的region供复制使用,则会触发FullGC。会STW且单线程回收。
G1核心参数
参数 | 作用 |
---|---|
-XX:+UseG1GC | 开启G1收集器 |
-XX:ParallelGCThreads | 设置GC工作的线程数量 |
-XX:G1HeapRegionSize | 设置region大小(1MB~32MB,且必须是2的N次幂) |
-XX:MaxGCPauseMillis | 设置暂停时间 |
-XX:G1NewSizePercent | 设置新生代初始空间,默认5% |
-XX:G1MaxNewSizePercent | 设置新生代最大空间比例,默认60% |
-XX:MaxTenuringThreshold | 最大年龄阈值(默认15) |
-XX:InitiatingHeapOccupancyPercent | 设置老年代触发GC的空间占比 |
-XX:G1MixedGCLiveThresholdPercent | 设置region中存活对象比例阈值,若小于则会在GC时优先回收,默认85% |
-XX:G1MixedGCCountTarget | 设置筛选回收阶段分几次做,默认8次 |