- 垃圾回收概念
- 垃圾回收算法
- 垃圾回收器
1 垃圾回收概念
1.1 可达性分析
选定活动的对象作为GC Roots,然后跟踪引用链条。
以下四种对象可以作为GC Root
- 虚拟机栈中正在引用的对象
- 本地方法栈中正在引用的对象
- 静态属性引用的对象
- 方法区常量引用的对象
对于没有被标记为可达的对象,进行回收。
1.2 引用类型和可达性级别
- 强引用:最常见的对象应用,只要有强引用,就不会回收
- 软引用:JVM认为内存不足时,才会去试图回收的对象(如缓存场景)
- 弱引用:随时可能被回收掉的对象
- 虚应用:不能通过它访问对象,对象被finalize以后,执行指定逻辑的机制
对应的,有5种可达性级别,分别是强可达、软可达、弱可达、幻象可达和不可达(意味着对象可以被清除了)。
2 垃圾回收算法
- 标记 - 清除算法
a) 内存碎片化 - 复制算法
a) 浪费一定空间
b) 对标记 - 清除算法的优化 - 标记 - 整理算法
a) 对标记清除算法的优化 - 分代回收算法
堆内存分成两部分,新生代:老年代 = 1:2
新生代采用复制算法,老年代采用标记整理算法
新生代内存不够分配时,新对象会分配到老年代,不会触发Minor GC
Minor GC一定次数后,未回收对象移动到老年代,通过-XX:MaxTenuringThreshold
设置次数
新对象会分配到新生代的Eden区,可以通过-XX:+PretenureSizeThreshold
设置大对象直接进入老年代的阈值
3 垃圾回收器
3.1 串行收集器
- Serial GC
-XX:+UseSerialGC
:单个线程来执行所有垃圾收集工作,适用单处理器机器,Client模式下JVM的默认选项 - Serial Old
-XX:+UseSerialOldGC
:老年代使用
串行使用单线程进行垃圾回收,回收时,所有的用户线程不能执行,进入STW,所以使用较少。
3.2 并行收集器
- Parallel GC
-XX:+UseParallelGC
- Parallel Old GC
-XX:+UseParallelOldGC
- ParNew GC
-XX:+UseParNewGC
:Serial GC的多线程版本
Server模式JVM的默认GC选项,多线程进行垃圾回收,可以设置GC时间或吞吐量等
-XX:ParallelGCThreads
设置用于垃圾回收的线程数
-XX:MaxGCPauseMills
设置最大垃圾收集停顿时间
-XX:GCTimeRatio
设置吞吐量大小,他的值是一个0-100之间的整数
-XX:+UseAdaptiveSizePolicy
打开自适应GC策略,以达到在堆大小、吞吐量和停顿时间之间的平衡点
吞吐量 = 用户代码运行时间 / (用户代码运行时间 + GC时间)
3.3 并发收集器
- CMS GC
-XX:+UseConcMarkSweepGC
设计目标是尽量减少停顿时间。
CMS基于标记 - 清除算法,会占用更多CPU资源,并和用户线程争抢,因为存在内存碎片化问题,长时间运行的情况下会发生Full GC,导致恶劣的停顿。
- G1
-XX:+UseG1GC
针对大堆内存设计的收集器,JDK1.9+默认选项,目标是替代CMS。
G1将堆分成固定大小的区域,区域之间是复制算法,但整体上可看作是标记 - 整理算法,可以有效地避免内存碎片,当分配不了大内存时,执行Full GC。
3.4 垃圾收集器组合
常见组合
- 新生代ParNew + 老年代CMS
- 新生代Parallel Scavenge + 老年代Parallel Old
- 新生代G1 + 老年代G1
参考文章
结语
本人所有博客仅用于学习记录,不做任何商业用途,如涉及侵权,还请联系删除,感谢阅读,欢迎留言,一起进步~