开发者社区> 牧小农> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

JVM性能优化(二)垃圾回收算法详解(3)

简介: JVM性能优化(二)垃圾回收算法详解
+关注继续查看

3.2、并行垃圾收集器


并行垃圾收集器在串行垃圾收集器的基础之上做了改进,将单线程改为多线程进行垃圾回收,这样可以缩短垃圾回收的时间(这里是指,并行能力较强的机器)

不过,并行垃圾收集器在收集的过程中也会暂停应用程序,这个和串行垃圾回收器是一样的,只是并行执行,速度更快些,暂停的时间更短一些。


3.2.1 parNew垃圾收集器


ParNew垃圾收集器是工作在年轻代上的,只是将串行的垃圾收集器改为了并行。

通过 -XX:UseParNewGC 参数设置年轻代使用ParNew回收器,老年代使用的依然是串行收集器。


测试:

image.png


# 参数
-XX:+UseParNewGC -XX:+PrintGCDetails -Xms16m -Xmx16m
# 打印的日志信息
[GC (Allocation Failure) [ParNew: 4416K->512K(4928K), 0.0015707 secs] 4416K->1818K(15872K), 0.0016110 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC (Allocation Failure) [Tenured: 10944K->1185K(10944K), 0.0086455 secs] 15872K->1185K(15872K), [Metaspace: 3835K->3835K(1056768K)], 0.0086862 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]

由以上信息可以看出,ParNew: 使用的是ParNew收集器,其他信息和串行收集器一致。


3.2.2 ParallelGC垃圾收集器


ParallelGC垃圾收集器工作机制和ParNewGC收集器一样,只是在此基础之上,新增了两个和系统吞吐量相关的参数,使得其使用起来更加的灵活和高效

相关参数如下:


-XX:+UserParallelGC: 年轻代使用ParallelGC垃圾回收器,老年代使用串行回收器


-XX:+UseParallelOldGC: 年轻代使用ParallelGC垃圾回收器,来年代使用ParallelOldGC垃圾回收器


-XX:MaxGCPauseMillis:


设置最大的垃圾收集时的停顿时间,单位为毫秒

需要注意的是,ParallelGC为了达到设置的停顿时间,可能会调整堆大小或其他的参数,如果堆的大小设置的较小,就会导致GC工作变的频繁,反而可能影响到性能。

使用这个参数需谨慎

-XX:GCTimeRatio


设置垃圾回收时间占程序运行时间的百分比,公式为 1/(1+n)

它的值为 0~100 之间的数字,默认值为99,也就是垃圾回收时间不能超过1%

-XX:UseAdaptiveSizePolicy:


自适应GC模式,垃圾回收器将自动调整新生代,老年代等参数,达到吞吐量,堆大小、停顿时间之间的平衡

一般用于,手动调整参数比较困难的场景,让收集器自动进行调整

#参数
-XX:+UseParallelGC -XX:+UseParallelOldGC -XX:MaxGCPauseMillis=100 -XX:+PrintGCDetails -Xms16m -Xmx16m
#打印的信息
[GC (Allocation Failure) [PSYoungGen: 4096K->512K(4608K)] 4096K->1683K(15872K), 0.0021804 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC (Ergonomics) [PSYoungGen: 1472K->0K(3584K)] [ParOldGen: 9577K->3990K(11264K)] 11049K->3990K(14848K), [Metaspace: 3828K->3828K(1056768K)], 0.0191664 secs] [Times: user=0.01 sys=0.00, real=0.02 secs]


3.3、CMS垃圾收集器


CMS全称 Concurrent Mark Sweep ,是一款并发的、使用标记-清除算法的垃圾回收器,该回收器是针对老年代垃圾回收的,通过参数 -XX:+UseConcMarkSweepGC进行设置的


CMS垃圾回收器的执行过程中如下:

image.png


初始化标记(CMS-initial-mark),标记root,会导致stw

并发标记(CMS-concurrent-mark),与用户线程同时运行

预清理(CMS-concurrent-preclean),与用户线程同时运行

重新标记(CMS-remark),会导致stw

并发清除(CMS-concurrent-sweep),与用户线程同时运行

调整堆大小,设置CMS在清理之后进行内存压缩,目的是清理内存中的碎片

并发重置状态等待下次CMS的处罚(CMS-concurrent-reset),与用户线程同时运行

测试:

image.png


#设置启动参数
-XX:+UseConcMarkSweepGC -XX:+PrintGCDetails -Xms16m -Xmx16m
#运行日志
[GC (Allocation Failure) [ParNew: 4416K->511K(4928K), 0.0050460 secs] 4416K->1954K(15872K), 0.0050891 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 
#第一步:初始3标记
[GC (CMS Initial Mark) [1 CMS-initial-mark: 6075K(10944K)] 6938K(15872K), 0.0003563 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
#第二步:并发标记
[CMS-concurrent-mark-start]
[CMS-concurrent-mark: 0.002/0.002 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
#第三步:预处理
[CMS-concurrent-preclean-start]
[CMS-concurrent-preclean: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
#第四步:重新标记
[GC (CMS Final Remark) [YG occupancy: 862 K (4928 K)][Rescan (parallel) , 0.0001950 secs][weak refs processing, 0.0000292 secs][class unloading, 0.0003607 secs][scrub symbol table, 0.0005794 secs][scrub string table, 0.0002047 secs][1 CMS-remark: 6075K(10944K)] 6938K(15872K), 0.0015122 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
#第五步:并发清理
[CMS-concurrent-sweep-start]
[CMS-concurrent-sweep: 0.002/0.002 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
#第六步:重置
[CMS-concurrent-reset-start]
[CMS-concurrent-reset: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

四、结束语


今天的内容就到这里了,文中详细描述了 垃圾回收算法和垃圾收集器的类型和作用,也通过案例给大家展示出来了,大家有什么疑问或者问题可以在下方留言,我会在第一时间回复大家,下一篇会讲最重要的垃圾收集器——G1垃圾收集器,感兴趣的小伙伴记得关注,大家加油,我是牧小农,我为自己代言。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
深入理解JVM - 垃圾回收算法
深入理解JVM - 垃圾回收算法
17 0
JVM从入门到入土之详解G1垃圾回收器
前言 文本已收录至我的GitHub仓库,欢迎Star:https://github.com/bin392328206/six-finger
45 0
JVM详解 --- 垃圾回收机制
JVM详解 --- 垃圾回收机制
141 0
【JVM】JVM系列之垃圾回收(二)(3)
  如果不进行垃圾回收,内存迟早都会被消耗空,因为我们在不断的分配内存空间而不进行回收。除非内存无限大,我们可以任性的分配而不回收,但是事实并非如此。所以,垃圾回收是必须的。
21 0
【JVM】JVM系列之垃圾回收(二)下
如果不进行垃圾回收,内存迟早都会被消耗空,因为我们在不断的分配内存空间而不进行回收。除非内存无限大,我们可以任性的分配而不回收,但是事实并非如此。所以,垃圾回收是必须的。
22 0
深入理解JVM虚拟机3:垃圾回收器详解
转自 JavaDoop HotSpot JVM 垃圾回收器 更新时间:2018-03-28 关于 JVM 内存管理或者说垃圾收集,大家可能看过很多的文章了,笔者准备给大家总结下。
1329 0
JS性能优化
下面是一些关于客户端JS性能的一些优化的小技巧: 1.关于JS的循环,循环是一种常用的流程控制。JS提供了三种循环:for(;;)、while()、for(in)。在这三种循环中 for(in)的效率最差,因为它需要查询Hash键,因此应尽量少用for(in)循环,for(;;)、while()循环的性能基本持平。
783 0
+关注
牧小农
业精于勤荒于嬉,行成于思毁于随。
134
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载