一、定义
GC(Garbage Collection),顾名思义。
二、如何判断一个对象是否是垃圾
(1)、引用计数法
被其他对象引用时计数+1,被其他对象删除引用时计数-1,可在应用中回收垃圾,无需Stop-The-World。
缺点:对象循环引用时无法判断是否为垃圾。
(2)、可达性分析
以GC Root为根向下遍历,不可达的对象即为垃圾。(理论基础:图论)
GC Root对象:
- 虚拟机栈中引用的对象
- 本地方法栈中引用的对象
- 方法区中静态变量引用的对象
- 方法区中常量引用的对象
- 活跃线程的引用对象
三、JVM堆内存的划分
新生代和老年代。内存分配比例1:2
新生代:Eden、Survivor0(From)、Surviror1(To),内存分配比例8:1:1。老年代:Old。
四、内存分配及回收时机
(1)、背景:IBM研究98%的对象是朝生夕死的。
(2)、内存分配:对象分配在Eden区,大对象直接分配在Old区。
(3)、触发Mirror GC时机:Eden区满了或者分配对象时Eden区内存不足会进行Minor GC(Young GC)。
(4)、Minor GC操作:
- 把Eden区存活的对象和From区存活的对象复制到To区,如果From中对象年龄到了15岁,把对象复制到老年代,然后把对象头中年龄+1,若To内存不足,直接进Old区。
- 回收完成后清空From区的内存,From区和To区定义互换。
(5)、特殊注意:
动态对象年龄,指Survivor中相同年龄的所有对象大小总和超过Survivor的一半,年龄大于等于该年龄的对象直接进入老年代。
年龄阈值:-XX:MaxTenuringThreshold。
大对象:-XX:+PretenuerSizeThreshold。
Eden和Survivor的比例:-XX:SurvivorRatio。
老年代和年轻代的比例:-XX:NewRatio。
(6)、Full GC
(7)、Major GC
触发Full GC的条件:
- 老年底空间不足
- 永久代空间不足(JDK7以及之前的版本)
- CMS GC时出现promotion failed,concurrent mode failure
- Mirror GC晋升到老年代的平均大小大于老年代的剩余空间
- 调用System.gc()
- 使用RMI来进行RPC或者管理的JDK应用,每小时执行一次
空间分配担保:
五、回收算法
(1)、复制算法
(2)、标记-清除(Mark and Sweep)
缺点:会造成内存碎片化。
(3)、标记-整理 (Compacting)
(4)、分代回收(Generational Collector 组合拳)
六、垃圾收集器
新生代收集器
(1)、Serial收集器(-XX:+UseSerialGC,复制算法)
(2)、ParNew收集器(-XX:UseParNewGC,复制算法)
(3)、Parallel Scavenge收集器(-XX:UseParallelGC,复制算法)
提高系统吞吐量
-XX:+UseAdaptiveSizePolicy 把调优交给系统去完成。
老年代收集器
(1)、Serial Old收集器()
(2)、Parallel Old收集器()
(3)、CMS收集器(标记-清除算法)
- 初始标记:stop-the-world
- 并发标记:
- 并发预清理:
- 重新标记:暂停虚拟机,
- 并发清理:
- 并发重置:
(4)、G1收集器(-XX:+UseG1GC,复制+标记-整理算法)
(5)、JDK11:EpsilonGC、ZGC
引用