JVM 垃圾回收器

我们都知道java的默认垃圾回收器是jdk1.8默认垃圾收集器Parallel Scavenge(新生代)+Parallel Old(老年代),但是一般我们都不会使用,但是在jdk1.9默认垃圾收集器
G1

我们可以采用以下命令来查看垃圾收集器:

java -XX:+PrintCommandLineFlagsjvm version
-XX:+PrintCommandLineFlagsjvm参数可查看默认设置收集器类型
-XX:+PrintGCDetails亦可通过打印的GC日志的新生代、老年代名称判断
-XX:InitialHeapSize=266287936 -XX:MaxHeapSize=4260606976 -XX:+PrintCommandLineFlags -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:-UseLargePagesIndividualAllocation -XX:+U
seParallelGC

1. 设置垃圾回收器参数以及意义

-XX:+UseSerialGC,虚拟机运行在Client模式下的默认值,Serial+Serial Old。

-XX:+UseParNewGC,ParNew+Serial Old,在JDK1.8被废弃,在JDK1.7还可以使用。

-XX:+UseConcMarkSweepGC,ParNew+CMS+Serial Old。

-XX:+UseParallelGC,虚拟机运行在Server模式下的默认值,Parallel Scavenge+Serial Old(PS Mark Sweep)。

-XX:+使用ParallelOldGC,并行清除+并行Old。

-XX:+使用G1GC,G1+G1。

步骤:
  1. 默认参数:-XX:+PrintGCDetails -XX:+PrintCommandLineFlags 用于打印具体的信息

  2. 添加上面的参数

修改后面的输出参数

-XX:InitialHeapSize=266287936 -XX:MaxHeapSize=4260606976 -XX:MaxNewSize=697933824 -XX:MaxTenuringThreshold=6 -XX:OldPLABSize=16 -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseConcMarkSweepGC -XX:-UseLargePagesIndividualAllocation -XX:+UseParNewGC 

2.垃圾回收概念

基本概念

任务(Parallel):指多条线程收集线程工作,但此时用户线程仍处于等待状态。

并发(Concurrent):指用户线程与垃圾收集线程同时执行(但不一定是空闲的,可能会交替执行),用户程序继续运行。而垃圾收集程序运行在另一个CPU上。

吞吐量就是CPU用于运行用户代码的时间与CPU总消耗时间的比值,即吞吐量=运行用户代码时间/(运行用户代码时间+垃圾收集时间)。

假设虚拟机总共运行了100分钟,其中垃圾收集花掉了1分钟,那吞吐量就是99%。

Minor GC 和 Full GC

新生代GC(Minor GC):指发生在新生代的垃圾收集动作,因为Java对象大多都具备朝生夕灭的特性,所以Minor GC非常频繁,一般恢复速度也比较快。具体原理见上一篇文章。

老年代GC(Major GC / Full GC):指发生在老年代的GC,出现了Major GC,经常会同时伴随至少一次的Minor GC(但非绝对的,在Parallel Scavenge收集器的收集策略里直接找到)进行Major GC的策略选择过程)。Major GC的速度一般会比Minor GC慢10倍以上。

3.垃圾回收器

新生代:

1. 串行

新生代串行的垃圾收集器,采用复制算法,垃圾恢复时必须暂停全部的工作线程,是一种独占式的垃圾收集器。

优点:简单,常做客户端模式桌面应用;
缺点:串行,无法利用高效多核心优势

2. 每新

新生代多线程垃圾回收器,是独占的,JavaSerial多了多线程,场合CMS配置使用;

优点:适用多核

3.并行清除收集器

并行Scavenge收集器也是一个配备的多线程新生代收集器,它也使用复制算法。

但是不同的是Parallel Scavenge关注的是货物,相当于整体的停顿时间占的比例,不介意,用户停顿的时长;

其他的都是关注用户停留时间、适合需要与用户交互的程序。

高货物则可以高效率地利用CPU时间,加速完成程序的攻击任务,主要适合在后方攻击而不需要过多交互的任务。

并行Scavenge收集器无法与CMS收集器配合使用,一般串行旧,并行旧

所以,java默认的垃圾回收器适合纯服务器开发;

老年代:

串行旧收集器

Serial Old 是串行收集器的旧版本,它同样是一个单线程收集器,使用“标记整理”(Mark-Compact)算法。

并行旧收集器

使用多线程和“标记整理”算法。所以在Parallel Old诞生以后,“货物优先”收集器终于有了比较名副其实的应用组合,在关注货物以及CPU资源敏感的场合,

内容管理系统

CMS(Concurrent Mark Sweep)收集器是一种以获取最短恢复停止时间为目标的收集器,它非常符合那些集中在互联网站或者B/S系统的服务端上的Java应用,这些应用都非常重视服务从名字上(“Mark Sweep”)就可以看出它是基于“mark-clear”算法实现的。

CMS收集器工作的整个流程分为以下4个步骤:

  • 初始标记(CMS初始标记):仅仅只是标记一下GC Roots能够直接关联到的对象,速度很快,需要“Stop The World”。

  • 并发标记(CMS并发标记):进行GC Roots Tracing的过程,在整个过程中的时间戳。

  • 重新标记(CMS
    备注):为了修改浪漫标记期间因用户程序继续运行而导致标记产生周期的那部分对象的标记记录,该阶段的停顿时间一般会比初始标记阶段稍长一些,但远比浪漫标记的时间短。此阶段也需要“Stop The World”。

  • 并发清除(CMS并发扫)

优点:CMS是一款优秀的收集器,它的主要优点在名字上已经体现了:并发收集、低停顿,因此CMS收集器也被称为并发低停顿收集器(Concurrent Low Pause Collector)。于B/S架构,与用户交流;

缺点:1.对CPU资源非常敏感 其实对于并发设计的程序都对CPU资源比较敏感。在并发阶段,虽然不会导致用户线程停顿,但因为会占用部分线程(或者说CPU资源)而导致应用程序变慢,总吞吐量会降低。CMS默认启动的恢复线程数量为(CPU数量+3)/4;2.标记清除算法导致的空间碎片3.恢复失败会返回到Serial Old;

G1收集器

G1(Garbage-First)收集器,它是一款面向服务端应用的垃圾收集器;

1. 硬件与并发 G1 能够充分利用多 CPU、多核环境下的硬件优势,使用多个 CPU 来进行整个“Stop The World”停顿时间;

2.分代收集与其他收集器相同,分代概念在G1中仍然可以保留。

3.空间整合G1从整体上来看是基于“标记-整理”算法实现的收集器;

4.可预测的停顿是G1相对CMS的一大优势,降低停顿时间是G1和CMS共同的关注点,但G1除了降低停顿外,还可以建立可建立的停顿时间模型,可以让用户明确预测指定在一个长度为M毫秒的时间片段内,

G1收集器之所以能够建立可预测的停顿时间模型,是因为它可以有计划地避免在整个Java堆中进行全区域的垃圾收集。G1跟踪每个区域里面的垃圾混凝土的价值大小(恢复所获得的)空间大小以及恢复需要时间的经验值),在后台维护一个优先列表,每次根据允许的收集时间,优先恢复值最大的Region(这就是Garbage-First名称的来由)。这种使用Region划分内存空间以及优先级的区域回收方式,保证了G1收集器在有限的期限内可以获得全部高的收集效率。

G1的适用场景:1.多核CPU、JVM内存占用增加的应用(纸上4G)2.运行过程产生大量碎片需要压缩,3.更可控的GC停顿周期,防止高并发下的雪崩;

4. 总结




如果觉得这篇文章对你有所帮助,
请点一下或者看看,是对我的肯定和支持~


请使用浏览器的分享功能分享到微信等