介绍
JVM里面的Throughtput收集器是一款关注吞吐量的垃圾收集器。该收集器是唯一一个实现了UseAdaptiveSizePolicy策略的收集器,允许用户通过指定最大暂停时间和垃圾收集时间占总时间的百分比,然后自适应调整JVM的参数来达到配置的目标。
Throughtput收集器
先上一张经典的垃圾收集器的图:
这张图相信很多人都看过,展示了各个垃圾收集器之间的搭配。平时我们说的Throughtput收集器就是图中红线框起来的几个收集器。下面会分别来介绍一些这几个收集器的特点和作用。
ParallelScavenge收集器
ParallelScavenge收集器收集的是新生代,使用的是Scavenge GC(Copying GC的另外一种叫法)。该收集器是并行的,可以同时多个线程一起执行copying阶段,在多处理器的场景下可以尽最大可能的提高minor gc的效率。ParallelScavenge收集器的目的是达到一个可控制的吞吐量,吞吐量=运行用户代码的时间/(运行用户代码的时间+垃圾收集的时间),虚拟机总共运行100分钟,其中垃圾收集器运行了1分钟,那么吞吐量就是99%。
关于ParallelScavenge收集器有个有趣的来历。HotSpot VM的开发者在开发垃圾收集器的时候都是在分代式框架中开发,并且希望第三方的开发者也是在这个框架中开发自定义的收集器,这样可以和其他收集器很好的配合在一起使用。后来有个开发者不想使用这个框架,于是靠一己之力实现了没有用框架的并行GC,并且这个并行GC的性能还是相当不错的,于是这个并行的GC就被放到了HotSpot VM里,这就是我们看到的ParallelScavenge收集器。这也是为什么这个收集器没法跟CMS配合使用,因为他们根本就不在一个框架内。
在使用ParallelScavenge收集器的时候,需要关于关注以下两个配置参数:
1、MaxGCPauseMills,这个参数控制允许GC最长的暂停时间,参数允许的值是一个大于0的毫秒数。设置该参数之后,VM会通过控制新生代的大小来达到暂停时间长短的控制的。不要认为把这个参数设置的越小越好,参数越小意味着新生代的空间越小,导致新生代执行垃圾收集的次数增加。举个例子,原来10秒钟执行一次minor gc,每次暂停100毫秒,现在把允许的暂停时间调低成80毫秒,可能导致每5秒钟就会执行一次minor gc,停顿时间降低了,但是吞吐量也下降了。
2、GCTimeRatio,垃圾收集时间占总时间的比率。该参数的值应该是一个大于0小于100的整数。如果把此参数设置为19,那允许的最大GC时间就占总时间的5% (即1 /(1 + 19)),默认值为99,就是允许最大1% (即1 /(1+99))的垃圾收集时间。
通过调整这两个参数就可以实现对吞吐量和暂停时间的控制,用户不用去关心新生代该设置多少,老年代该设置多少,只需要设置好这两个值,剩下的就交给虚拟机吧,它会帮你调整好对应的大小。新生代可以通过这种方式实现,那么老年代是否也有类似的方式来实现呢,答案是有的,就是图中的Parralled Old。
Parralled Old收集器
Parralled Old收集器是ParallelScavenge的老年代版本。使用的算法是Mark-Compact。Parralled Old收集器是在JDK1.6之后才出现的,在此之前如果新生代选择使用ParallelScavenge,那么老年代只能选择使用Serial Old,也就是说只能使用单线程收集,为了弥补这个不足,于是开发了Parallel Old收集器。有了Parallel Old收集器之后,Throughtput收集器才真正显示出它的强大之处,在吞吐量和CPU敏感的情况下,都可以考虑使用Parallel Scavenge+Parallel Old的组合。
Paralled Old收集器的运行示意图如下:
Serial Old收集器
Serial Old收集器是一款传统的单线程垃圾收集器,使用Mark-Sweep-Compact算法。这个收集器主要是在Client模式下使用。该收集器的用途有两个:一个是在JDK1.5之前与ParallelScavenge收集器配合使用;第二个用途是作为CMS收集器的后备预案,在CMS发生并发模式失效的时候使用Serial Old收集器进行一次完整的STW的垃圾回收。
Serial Old收集器的运行示意图如下:
收集器配置
在JDK1.8下,使用Throughtput收集器有两种配置:
1、-XX:+UseParallelGC或者-XX:+UseParallelOldGC,这两个配置下任选一个使用的收集器都是ParallelScavenge+Parralled Old。这与网上大多数说介绍是不一样的,网上大多数介绍是说UseParallelGC配置下使用的是ParallelScavenge+Serial Old,JDK1.8下已经进行了统一,Serial Old已经不再是默认的选择。
2、如果想使用Serial Old作为老年代的垃圾收集器可以这样配置:-XX:+UseParallelGC -XX:-UseParallelOldGC。
GC日志说明
-XX:+UseParallelGC或者-XX:+UseParallelOldGC参数下的日志:
2018-04-29T14:55:42.360-0800: [Full GC (System.gc()) [PSYoungGen: 1421K->0K(76288K)] [ParOldGen: 8K->1257K(175104K)] 1429K->1257K(251392K), [Metaspace: 3205K->3205K(1056768K)], 0.0054702 secs] [Times: user=0.02 sys=0.01, real=0.00 secs] |
-XX:+UseParallelGC -XX:-UseParallelOldGC参数下的日志:
2018-04-29T15:05:43.409-0800: [Full GC (System.gc()) [PSYoungGen: 1449K->0K(76288K)] [PSOldGen: 8K->1265K(175104K)] 1457K->1265K(251392K), [Metaspace: 3206K->3206K(1056768K)], 0.0034926 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] |
我使用了System.gc()分别在两种配置下触发GC,通过对比可以发现只有在老年代的收集下是不一样的,第一个用的是ParOldGen,对应的是Parralled Old收集器;第二个用的是PSOldGen,对应的是Serial Old收集器。新生代收集日志PSYoungGen对应的就是Parallel Scavenge收集器。
收集器调优
在使用Throughtput收集器的时候强烈不建议手动指定新生代大小和老年代大小,因为这将废弃虚拟机的自适应调整策略。也就意味着你配置的MaxGCPauseMills和GCTimeRatio参数很难真正起作用。用户只需要指定最大最小堆内存,以及MaxGCPauseMills和GCTimeRatio参数即可,剩下的交给VM去处理吧,它会帮你调整到最佳状态,这也是非常人性化的。VM具体的调整包含调整新生代和老年代的大小,以及调整新生代晋升到老年代的年龄等。
以上设置的参数,MaxGCPauseMills优先级最高,如果设置了这个值,新生代和老年代会随之进行调整,直到满足对应的停顿时间的目标。一旦这个目标达成,堆的总容量开始增大,直到运行时间达到比率GCTimeRatio设定值。这两个目标达成后,JVM尝试缩小堆大小,尽可能以最小堆来满足这两个目标。
其他的一些东西
ParNew与Parallel Scavenge对比
ParNew也是一个新生代的并行GC,ParNew的存在主要是为了配合CMS使用,如果没有ParNew,CMS只能搭配单线程垃圾回收。ParNew与Parallel Scavenge对比有以下几种不同:
1、ParNew使用的是广度优先来遍历对象图,Parallel Scavenge使用的是深度优先来遍历对象图
2、ParNew没有实现UseAdaptiveSizePolicy策略,而Parallel Scavenge实现了这个策略
3、ParNew可以和CMS搭配使用,而Parallel Scavenge不能与CMS搭配使用
并行GC线程数
通过-XX:ParallelGCThreads=X来设置并行GC的线程数量,默认情况下跟处理器个数一致。
总结
1、Throughtput收集器有两种参数,Minor GC和Full GC
2、通过Throughtput收集器的动态调整策略是垃圾回收调优的很好切入点,能有效的减少JVM内存使用
3、当需要追求吞吐量的时候,Throughtput总是一个不错的选择
----------------------------------------------------------------
欢迎关注我的微信公众号:yunxi-talk,分享Java干货,进阶Java程序员必备。
相关推荐
`throughtput.awk`:吞吐量是指网络在单位时间内传输数据的能力,是衡量网络性能的关键指标。这个脚本可以帮助用户分析仿真中的网络带宽利用率和数据传输速度,从而评估网络的效率和容量。 在NS2仿真中,通过这些...
- throughtput.awk:计算网络的平均吞吐量。 - wire_wireless.tcl:配置有线无线混合网络的TCL脚本。 - wireless.tcl:专门用于无线网络模拟的TCL脚本。 - mflood.cc/mflood.h:这是实现多播路由的源代码,展示如何...
基于springboot大学生就业信息管理系统源码数据库文档.zip
基于java的驾校收支管理可视化平台的开题报告
时间序列 原木 间隔5秒钟 20241120
毕业设计&课设_基于 Vue 的电影在线预订与管理系统:后台 Java(SSM)代码,为毕业设计项目.zip
基于springboot课件通中小学教学课件共享平台源码数据库文档.zip
基于java的网上购物商城的开题报告
Delphi人脸检测与识别Demo1fdef-main.zip
基于java的咖啡在线销售系统的开题报告
基于java的自助医疗服务系统的开题报告.docx
内容概要:本文档全面介绍了Visual Basic(VB)编程语言的基础知识和高级应用。首先概述了VB的基本特性和开发环境,随后详细讲述了VB的数据类型、变量、运算符、控制结构、数组、过程与函数、变量作用域等内容。接着介绍了窗体设计、控件使用、菜单与工具栏的设计,文件操作、数据库访问等关键知识点。最后讨论了VB的学习方法、发展历史及其在桌面应用、Web应用、数据库应用、游戏开发和自动化脚本编写等领域的广泛应用前景。 适合人群:初学者和中级程序员,尤其是希望快速掌握Windows桌面应用开发的人群。 使用场景及目标:①掌握VB的基础语法和开发环境;②学会使用VB创建复杂的用户界面和功能完整的应用程序;③理解数据库操作、文件管理和网络编程等高级主题。 其他说明:Visual Basic是一种简单易学且功能强大的编程语言,尤其适合用于开发Windows桌面应用。文中不仅覆盖了基础知识,还包括了大量的实用案例和技术细节,帮助读者快速提升编程技能。
基于java的疫情期间高校防控系统开题报告.docx
基于springboot+vue社区老年人帮扶系统源码数据库文档.zip
基于java的超市商品管理系统的开题报告.docx
基于SpringBoot房屋买卖平台源码数据库文档.zip
xdu限通院23微处理器系统与应用大作业(两只老虎),适应于汇编语言keil软件,
<项目介绍> - 新闻类网站系统,基于SSM(Spring、Spring MVC、MyBatis)+MySQL开发,高分成品毕业设计,附带往届论文 - 不懂运行,下载完可以私聊问,可远程教学 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 --------