java虚拟机垃圾回收器

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lingmao555/article/details/80978489
java垃圾回收算法不止一种,当然垃圾回收器也不止一种,本文主要介绍HotSpot虚拟机中的垃圾收集器。

一.Serial收集器(串行回收器)

1.新生代串行垃圾回收器

定义:指的是使用单线程进行回收的回收器

特点:
A.每次回收时,串行回收器只有一个工作线程。
B.它是独占的垃圾回收(中间应用程序会停顿)。

C.实现相对简单,逻辑处理特别高效,没有线程切换的开销,使用的是复制算法。

使用:

 "-XX:+UseSerialGC":添加该参数来显式的使用串行垃圾收集器;

2.老年代串行回收器

和新生代串行回收器基本上一样,也是一种独占的,串行回收期。特点是会比新生代回收器占用更长的时间,使用的是压缩算法。

若要使用老年代串行回收器,可以尝试使用以下参数:

 "-XX:+UseSerialGC":新生代和老年代都使用串行回收器
 "-XX:+UseParNewGC":新生代使用ParNew回收器,老年代使用串行回收器;
 "-XX:+UseParallelGC":新生代使用ParallelGC回收器,老年代使用串行回收器;

二.并行回收器

3.新生代ParNew回收器

ParNew回收器是一个工作在新生代的垃圾回收器,它只是将简单的将串行回收多线程化,他的回收策略,算法,以及参数和新生代串行回收器一样。

使用场景:
在并发能力比较强的cpu上它的停顿时间要短与串行回收器,而在单cpu或者并发能力较弱的系统中,并行回收器的效果不会比串行回收器好,由于多线程的压力,它的实际表现可能比串行回收器差。  在Server模式下,ParNew收集器是一个非常重要的收集器,因为除Serial外,目前只有它能与CMS收集器配合工作;

使用:

 "-XX:+UseConcMarkSweepGC":指定使用CMS后,会默认使用ParNew作为新生代收集器;
 "-XX:+UseParNewGC":强制指定使用ParNew;    
 "-XX:ParallelGCThreads":指定垃圾收集的线程数量,ParNew默认开启的收集线程与CPU的数量相同;

4.新生代ParallelGC回收器

新生代的ParallelGC回收器表面上和ParNew回收器一样都是多线程,独占式的。它有一个很重要的特点就是,很关注吞吐量。

两个重要的调整参数

(A)、"-XX:MaxGCPauseMillis"
      控制最大垃圾收集停顿时间,大于0的毫秒数;
      MaxGCPauseMillis设置得稍小,停顿时间可能会缩短,但也可能会使得吞吐量下降;
      因为可能导致垃圾收集发生得更频繁;
(B)、"-XX:GCTimeRatio"
      设置垃圾收集时间占总时间的比率,0<n<100的整数;
      GCTimeRatio相当于设置吞吐量大小;
      垃圾收集执行时间占应用程序执行时间的比例的计算方法是:
      1 / (1 + n)
      例如,选项-XX:GCTimeRatio=19,设置了垃圾收集时间占总时间的5%--1/(1+19);
      默认值是1%--1/(1+99),即n=99;
垃圾收集所花费的时间是年轻一代和老年代收集的总时间;
如果没有满足吞吐量目标,则增加代的内存大小以尽量增加用户程序运行的时间;

5、Parallel Old收集器

Parallel Old垃圾收集器是Parallel Scavenge收集器的老年代版本;

特点:

   针对老年代;采用"标记-整理"算法;多线程收集;

使用:

 "-XX:+UseParallelOldGC":指定使用Parallel Old收集器;

6.CMS

CMS:并发标记清理(Concurrent Mark Sweep),也称为并发低停顿收集器,CMS回收器主要关注于

系统停顿时间。使用标记清除算法,同时它又是一个使用多线程并行回收的垃圾回收器。

STW:表示Stop-the-world

橘色表示独占式的进程,其他过程和用户程序一起进行的。。。

特点:

    基于"标记-清除"算法(不进行压缩操作,产生内存碎片);以获取最短回收停顿时间为目标;并发收集、低停顿;

CMS的三个缺点

(A)、对CPU资源非常敏感

CMS是多线程的,设置合理的工作线程数量对系统的性能有很重要的影响

CMS默认启动的并发线程数是(ParallelGCThreads+3)/4,ParallelGCThreads表示GC并行时使用的
线程数量。如果新生代使用ParNew(经常配合使用),那么ParallalGcThreads也就是新生代GC的线程数量。
并发线程数量可以通过-XX:ConcGCThreads或者-XX:ParallelCMSThreads手工设定,设置这个参数时
要小心,当CPU资源比较紧张的时候,受到CMS回收器线程的影响,应用程序的性能在垃圾回收阶段可能
会非常糟糕。

(B)、浮动垃圾

 在并发清除时,用户线程新产生的垃圾,称为浮动垃圾;

CMS回收器不是独占式的,垃圾是不断产生的,CMS回收器不会等待堆满时才回收,当达到某个阀值 时就进行回收,
 这个值通过"-XX:CMSInitiatingOccupancyFraction"设定

一般为68,表示当老年代空间使用率达到  68%时,就会执行一次CMS回收。

注意:如果内存增长缓慢,则可以设置一个稍大的值,大的阀值可以有效降低CMS的触发频率,减少老年代回收次数
可以明显改善应用程序的性能,反之,如果应用程序内存使用率增长很快,则应该降低这个阀值,以避免频繁
触发老年代串行收集器。

(C)、内存碎片

  CMS基于标记清除算法实现,在垃圾回收时会产生大量的碎片,在即使堆内存中有较大的空间,而分配大的内存空间时
  无法找到足够的连续内存,从而需要提前触发另一次Full GC动作。这样对系统的性能不利。

"-XX:+UseCMSCompactAtFullCollection"开关可以使CMS在垃圾收集完成之后,进行一次内存碎片整理,内存碎片的整理不是并发进行的。

"-XX:+CMSFullGCsBeforeCompaction"参数用于多少次CMS之后,进行一次内存压缩。

7.G1垃圾回收器

G1(GarbageFirst)垃圾收集器是当今垃圾回收技术最前沿的成果之一,同优秀的CMS垃圾回收器一样,G1也是关注最小时延的垃圾回收器,也同样适合大尺寸堆内存的垃圾收集,官方也推荐使用G1来代替选择CMS。G1最大的特点是引入分区的思路,弱化了分代的概念,合理利用垃圾收集各个周期的资源,解决了其他收集器甚至CMS的众多缺陷。在JDK1.7之后引入。

G1使用了全新的算法,特点如下:
并行性:G1在回收期间,可以由多个线程同时工作,有效利用多核的计算能力。
并发性:G1拥有与应用程序交替执行的能力,部分工作可以和应用程序同时执行,因此一般来说
不会再整个回收期间完全阻塞应用程序。
分代GC:G1依然是一个分代收集器,但是和之前回收器不同,它同时兼顾年轻代和老年代。对比其他收集器只在年轻代或者老年代有很大不同。
空间整理:G1在回收过程中,会进行适当的对象移动,不像CMS只是简单地标记清理对象
在若干次GC后,CMS必须进行一次碎片的整理。而G1不同,它每次回收都会有效地复制对象,减少
空间碎片。
可预见性:由于分区的原因,G1可以只选取部分区域进行内存回收,这样输下了回收的范围,
因此对于全局停顿也能得到较好的控制。

设置相关的参数:

3、设置参数
 "-XX:+UseG1GC":指定使用G1收集器;    

"-XX:InitiatingHeapOccupancyPercent":当整个Java堆的占用率达到参数值时,开始并发标记阶段;默认为45;
 "-XX:MaxGCPauseMillis":为G1设置暂停时间目标,默认值为200毫秒;    

"-XX:G1HeapRegionSize":设置每个Region大小,范围1MB到32MB;目标是在最小Java堆时可以拥有约2048个Region;
 

【参考资料】

《深入理解Java虚拟机:JVM高级特性与最佳实践》

《实战java虚拟机》

这是结尾。。。

猜你喜欢

转载自blog.csdn.net/lingmao555/article/details/80978489