一、垃圾回收相关理论
Stop-The-Word(STW):JVM要执行GC而停止应用程序的运行,STW会在任何一种GC算法中发生,除了GC线程之外所有线程都处于等待状态,多数GC优化通过减少STW的时间来提升系统吞吐量。
Safepoint(安全点):分析对象引用关系的时候,所有线程在这个点被冻结,不可以出现对象引用关系还在变化的情况,分析结果要在某个节点有确定性,该节点叫做安全点。产生安全点的地方有:方法调用、循环跳转、异常跳转等。GC时让线程跑到安全点再停顿下来。安全点数量要适中,太少要增加GC等待时间,太多要增加程序运行的负荷。
JVM运行模式:Server,启动慢,程序运行到稳定期,运行速度快,因为此模式启动的是重量型虚拟机,对程序优化更多。Client,则反之。
二、垃圾收集器
1.年轻代常见垃圾收集器:
1.1 Serial收集器(-XX:+UserSerialGC,复制算法)
特点:单线程收集,垃圾收集时暂停所有工作线程。
简单高效,Client模式下默认的年轻代垃圾收集器。
1.2 ParNew收集器(-XX:UserParNewGC,复制算法)
特点:多线程收集,其余行为特点和Serial收集器一样。
单核执行效率不如Serial收集器,在多核下执行才有优势。
除Serial以外,只有ParNew才能与CMS配合。
1.3 Parallel Scavenge收集器(-XX:+UseParallelGC,复制算法)
特点:也是多线程收集,比起前面缩短用户线程停顿时间更关注系统吞吐量,更适合后台运算任务而不是用户交互。
多核执行下才有优势,Server模式下默认的年轻代垃圾收集器。
2.老年代常见垃圾收集器
2.1 Serial Old收集器(-XX:+UseSerialOldGC,标记-整理算法)
Serial的老年代版本的垃圾收集器
特点:单线程收集,垃圾收集时暂停所有工作线程。
简单高效,Client模式下默认的老年代垃圾收集器。
2.2 Parallel Old收集器(-XX:+UseParallelOldGC,标记-整理算法)JDK6之后出现的
特点:多线程、吞吐量优先。
2.3 CMS收集器(-XX:+UseConcMarkSweepGC,标记-清除算法)
步骤:初始标记(CMS initial mark)标记GC roots能直接关联到的对象,速度快。(需要STW)
并发标记(CMS concurrent mark)进行GC roots tracing,寻找引用链。
重新标记(CMS remark)为了修正并发标记期间,因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录。(需要STW)
并发清除(CMS concurrent sweep)
特点:以获取最短回收停顿时间为目标、希望系统停顿时间最短,以给用户带来较好的体验。
使用标记--清除算法,产生大量空间碎片。
对CPU资源敏感。GC线程需要和用户线程并发进行。
无法收集浮动垃圾。也就是并发清理时用户线程产生的垃圾。
三、G1(Garbage-First)垃圾收集器(-XX:+UseG1GC,复制算法+标记-整理算法)
(了解)
步骤:
初始标记(Initial Marking)
并发标记(Concurrent Marking)
最终标记(Final Marking)
筛选回收(Live Data Counting and Evacuation)
特点:G1(Garbage-First)收集器,是一款面向服务端应用的收集器。
并发、并行。
空间整合,G1收集器采用标记整理算法,不会产生内存空间碎片。
可预测停顿,能建立可预测的停顿时间模型,能让使用者明确指定在一个长度为M毫秒的时间片段内,消耗在垃圾收集上的时间不得超过N毫秒。
将整个Java堆内存划分成多个大小相等的Region,年轻代和老年代不再物理隔离。