jvm - GC垃圾回收器(一)年轻代+老年代

四种主要的垃圾回收器:
    * Serial(串行垃圾回收器):后台只有一个线程负责垃圾回收,当它回收时,会暂停所有用户线程,所以不适合服务器环境。(一个人打扫,其他客人都得等着)
    * Parallel(并行垃圾回收器):后台有多个线程负责垃圾回收,当它们回收时,同样暂停所有用户线程,适用于科学计算/大数据处理等若交互场景。(一堆人打扫,客人都得等着)
    * CMS(并发标记清除,简称 并发垃圾回收器):(它其实分4步,有两步其实还是会暂停一下,但效率已经高很多了)(边吃边打扫)


    * G1(Garbage first回收器):jdk1.8推出,是jdk1.9的默认垃圾回收器,jdk11出了个ZGC(更吊);

G1将堆内存分割成不同的区域,然后并发地对其进行垃圾回收。

 

查看默认的垃圾回收器是哪个:
java -XX:+PrintCommandLineFlags -version     (红字显示是并行垃圾回收器)

如果想改成第一种串行垃圾回收器,则 -XX:+UseSerialGC ,使用该命令后(在IDEA中设置),查看:

而查看JVM参数初始设定的命令是: java -XX:+PrintFlagsInitial

 

之前说垃圾回收器有4种,但是从源码中看,其实默认的垃圾回收器共6种:(其实还有一种叫UseSerialOldGC,基本废除淘汰了,加上它,就是所谓的7大垃圾回收器)

 

Serial Copying = UseSerialGC
Parallel Scavenge = UseParallelGC    1.8以及之前默认UseParallelGC,1.9默认使用G1.
ParNew = UseParNewGC

Serial MSC(Serial Old) = UseSerialOld    已废除
Parallel Compacting(Parallel Old) = UseParallelOld
CMS = UseConcMarkSweepGC

部分参数的对照翻译表:
(这些参数显示在PrintGCDetails里面,说明新生代和老年代用的是什么垃圾收集器)

叉表示从jdk1.8开始,新生代使用的垃圾回收器对应的在养老区的垃圾回收器不推荐使用。(不推荐不代表不使用,事实上从左往右数第二个叉在默认情况下并未起作用,见二(自己解释一下:原来默认是ParNew+Serial Old,在jdk1.8不推荐了,但是默认还是ParNew+Serial Old))
(如在新生代使用Serial垃圾回收器,则在养老区不能使用CMS垃圾回收器,而只能使用SerialOld垃圾回收器)

A指向B,表示:当启用A,会跟着配套启用B使用。
在之前,年轻代的Serial、Parallel Scavenge、ParNew都默认使用Serial Old。
在jdk1.8开始,不推荐Parallel Scavenge和ParNew和Serial Old配套使用了,而是让Parallel Scavenge和Parallel Old相互激活,让CMS激活ParNew(Serial Old作为CMS的后备老年代垃圾回收器)。(Serial还是和Serial Old配合,这点不变)

 

一、串行GC(Serial)(Serial Copying)

适合单cpu服务器

即jvm客户端默认还是使用Serial作为垃圾回收器、适合于单CPU环境

 

因为现在计算机都不止一个CPU,所以Serial垃圾回收器基本已经废除了;
因为只有一个线程负责GC,而又只有一个CPU,所以不涉及在多个GC线程之间切换,所以在一个CPU的情况下,Serial垃圾回收器可以获得最高的单线程垃圾收集效率。

 

二、并行GC(ParNew)

ParNew是很多JVM在新生代下的默认垃圾回收器: 难道不是Parallel吗???是的!所以这里不用在意,当它写错了

 

三、并行回收GC(Parallel)(Parallel Scavenge) 默认的那个

(俗称:吞吐量优先收集器)
年轻代默认使用
和Parallel Old相互激活

使用上面任意一个后,老年代默认开启使用Parallel Old(因为Parallel和Parallel Old相互激活)

读完还是没懂,ParNew和Parallel的区别是什么:
Parallel它关注的重点是:

所以,为了使用这个Parallel垃圾回收器,在IDEA中配置 -XX:UseParallelGC 或 -XX:UseParallelOldGC即可(它俩可以相互激活),因为:(见红色方框)

 

四、并行GC(Parallel Old)(Parallel MSC)

它和Parallel可以相互激活

Parallel Old正是为了在老年代提供同样吞吐量优先的垃圾回收器:因为年轻代中Parallel Scavenge和ParaNew相比的优点就是提供了更高吞吐量,但只是提供了年轻代更高的吞吐量,而无法保证整体的高吞吐量。所以从jdk1.8开始,不再将Parallel Scavenge与Serial Old绑定,而是将Parallel Scavenge与Parallel Old绑定,以保证整体的高吞吐量。

只使用3,也可以开启Parallel Old

 

五、并发标记清除GC(CMS)

(其他的老年代收集器都使用标记整理算法,所以这里准备讲的垃圾回收器CMS的缺点很明显:有内存碎片)
用在养老区;
标记清除是GC的第三种算法,缺点是遍历两次、有内存碎片;
互联网公司一般都用CMS垃圾回收器;

CMS有4步:

三者合作:

CMS有4步:
7步的详见:https://www.codercto.com/a/45937.html

1、初始标记(STW)
从垃圾回收的“根对象”开始,且只扫描直接与“根对象”直接关联的对象,并做标记,在此期间,其他线程都会停止。耗时短。

2、并发标记,和用户线程一起(并发)
从GC Root 开始对堆中对象进行可达性分析,找出存活的对象。

3、重新标记(STW)

4、并发清除,和用户线程一起(并发)


CMS总结:

在运行结果中也能看到4步:

优点:
并发收集,停顿低
缺点:
并发执行,对CPU资源的压力大;

采用的标记清除算法会导致大量内存碎片。

代码演示:
-XX:+UseConcMarkSweepGC

结果:
明明指定了一个垃圾回收器CMS,但是却不光显示了老年代用CMS,还显示了年轻代:使用ParNew(原因:它们是配套使用的,甚至老年代还有一个备选方案)

 

说穿了,配-XX:+UseConcMarkSweepGC   (CMS)
最后实现的就是:

 

六、串行GC(Serial Old)(Serial MSC)

其实就是年轻代的串行搬到了老年代而已

 

结果:

 

6中垃圾回收器(G1还没讲)总结:

一些新老代垃圾回收器的经典组合:

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值