Stop-the-World
- JVM由于要执行GC而停止了应用程序的执行(处于stop-the-world的状态时,除了GC的线程以外的所有线程都处于等待状态,知道GC完成)
- 任何一种GC算法中都会发生
- 多数GC优化通过减少stop-the-world发生的事件来提高程序性能,达到高吞吐低停顿的特点
Safepoint:安全点
- 分析过程中对象引用关系不会发生变化的点(在可达性分析中,要分析哪个对象没有引用的时候,必须在一个快照的状态进行,所有线程都冻结了,不可以出现分析过程中对象引用还在变化的情况,因此分析结果需要在某个节点具有确定性,该节点就是安全点)
- 产生Safepoint的地方:方法调用、循环跳转、异常跳转等
- 安全点的数量适中(太少会让GC等待太长时间,太多会增加程序的负荷)
JVM的运行模式
- Server(启动较慢,但是启动居于稳定之后,server的运行速度比client要快,因为server采用的是重量级的虚拟机,对程序做了更多优化)
- Client(启动较快,Client采用的是轻量级的虚拟机)
常见的垃圾回收器
上面年轻代的收集器,下面是老年代,有连线的表示可以搭配起来是用
年轻代的收集器:
Serial收集器(-XX:UseSerialGC,复制算法,是java历史最悠久也最基本的垃圾收集器,在1.3以前年轻代收集的唯一选择)
- 单线程收集,进行垃圾收集时,必须暂停所有工作线程
- 简单高效,依然是现在Client模式下的默认年轻代收集器(用户在桌面管理系统中,一般分配给虚拟机的内存不会很大,收集几十兆、一两百百兆的停顿时间会在几十毫秒到一百毫秒之间,只要不是频繁的发生,是可以接受的)
ParNew收集器(+XX:UseParNewGC,复制算法,在Server模式下是非常重要的收集器,除了Serial以外只有它能与CMS配合工作)
- 多线程收集,其余的行为、特点和Serial收集器一样(是Server模式下的首选的年轻代收集器)
- 单核执行效率不如Serial,在多核下执行才有优势
Parallel Scavenge收集器(+XX+UseParallelGC,复制算法)
吞吐量=运行用户代码时间/(运行用户代码时间+垃圾收集时间)
- 比起关注用户线程停顿时间,更关注系统的吞吐量
- 在多核下执行才有优势,Server模式下的默认年轻代收集器
如果对于垃圾收集器运作原理不太了解,以至于在优化过程中遇到困难的时候会使用Parallel Scavenge收集器配合-XX:UseAdaptiveSizePolic会把内存管理的调优交给虚拟机完成
老轻代的收集器:
Serial Old收集器(+XX:+UseSerialOldGC,标记-整理算法)
- 单线程收集,进行垃圾收集时,必须暂停所有工作线程
- 简单高效,Client模式下的默认老年代收集器
Parallel Old收集器(-XX:+UseParallelOldGC,标记-整理算法,JDK6开始引入)
- 多线程,吞吐量优先
CMS收集器(-XX:+UseConcMarkSweep,标记-清除算法,几乎占据了JVM老年代垃圾收集的半壁江山,几乎能做到垃圾回收线程和工作线程同时工作,几乎是因为它还是不能做到stop-the-world,不过它尽可能的缩短了停顿时间)
- 初始标记:stop-the-world(只做标记,虽然暂停了JVM但是很快完成了)
- 并发标记:并发追溯标记,程序不会停顿
- 并发预清理:查找执行并发标记阶段从年轻代晋升到老年代的对象
- 重新标记:stop-the-world 暂停虚拟机,扫描CMS堆中的剩余对象(扫描从跟对象开始,向下追溯,并处理关联,这一步会相对较慢)
- 并发清理:清理垃圾对象,程序不会停顿
- 并发重置:重置CMS收集器的数据结构
有个显著的缺点:因为CMS使用的是标记清除算法,不会对存活对象压缩,会带来空间碎片化问题,如果需要分配一个连续的大空间就只能触发FullGC了
Garbage First :G1收集器(-XX:+UseG1GC,复制+标记-整理算法,既用于年轻代又用于老年代的收集器,未来是为了替换JDK5发布的CMS收集器)
- 并发和并行(使用多个cpu缩短stop-the-world的时间,与用户线程并发执行)
- 分代收集(独立管理整个堆,但是使用不同的方法处理新创建的对象和已经存活了一段时间的对象,效果更好)
- 空间整合(标记整理算法,解决碎片化问题)
- 可预测的停顿(可以用户可以设置垃圾收集工作不得超过N毫秒)
G1会将整个java堆内划分成多个大小相等的Region。虽然还保留了年轻代和老年代的概念,但是他们不再是物理隔离的,他们一部分可以是不连续的Region集合
另外值得一提的是JDK11新推出的2个特别牛逼的垃圾收集器:EpsilonGC 和ZGC,感兴趣的可以了解下