前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JVM系列--还不会选择合适的垃圾收集器?

JVM系列--还不会选择合适的垃圾收集器?

作者头像
田维常
发布2020-04-23 15:34:36
1.6K0
发布2020-04-23 15:34:36
举报

Java是流行多年的编程语言,深受广大小伙伴的欢迎,其主要有两个特点:

  • 跨平台:write once run anywhere,一次编写,到处运行。这里的一次编写指的是从.java文件被编译成.class文件的过程。到处运行:是指安装了JVM的不同操作系统(平台),c.lass文件就可以在该平台上进行运行了,有JVM负责解释或者编译执行字节码。
  • 垃圾回收:程序员不用再像使用C或者C++开发时候关心内存的分配和释放了,内存的管理是有垃圾回收器来管理的,减少了内存泄漏的概率。垃圾回收器由JVM的后台线程实现垃圾对象的回收。

垃圾收集器

JVM中的垃圾收集器一直在不断发展中,比较成熟的垃圾回收器有串行回收器、并行回收器、标记回收器、垃圾优先回收器等,JDK11中引入了ZGC,JDK12中引入另外一款垃圾回收器Shenandoah。

虽然垃圾回收器在不断更新,但是垃圾收集算法基本没变:

复制、标记清除、标记压缩。

不同的垃圾收集器都是基于上面这些基本方法实现的,不同垃圾收集器的区别在于亮点:

  1. 使用的算法不一样
  2. 实现是后台线程采用的并行/并发方式不一样

本文主要来聊下面几种垃圾回收器的特性及如何选择

参考:JVM的7种垃圾收集器的特点及使用场景

G1收集器

G1 的全称是 Garbage-First,意为垃圾优先,哪一块的垃圾最多就优先清理它。

G1 GC 最主要的设计目标是:将STW(stop the world) 停顿的时间和分布,变成可预期且可配置的。

事实上,G1 GC 是一款软实时垃圾收集器,可以为其设置某项特定的性能指标。例如可以指定:在任意 xx 毫秒时间范围内,STW停顿不得超过 yy 毫秒。举例说明:任意 1 秒内暂停时间不超过 5 毫秒。G1 GC 会尽力达成这个目标(有很大概率会满足,但并不完全确定)。

JDK 7开始使用,JDK8非常成熟,JD 9默认的垃圾收集器,适用于新老生代。

G1致力于在多CPU和大内存服务器上对垃圾回收提供软实时目标(soft real -time goal)和高吞吐量(high throuhput)。

判断是否需要使用G1收集器?
  1. 50%以上的堆被存活对象占用
  2. 对象分配和晋升的速度变化非常大
  3. 垃圾回收时间比较长
ZGC收集器

ZGC(Z Garbage Collector)作为一种比较新的收集器,目前还没有得到大范围的关注。作为一款低延迟的垃圾收集器,它有如下几个亮点:

•停顿时间不会超过 10ms•停顿时间不会随着堆的增大而增大(控制停顿时间在10ms内)

•支持堆的大小范围很广(8MB-16TB)

在ZGC中,连逻辑上的也是重新定义了堆空间(不区分年轻代和老年代),只分为一块块的page,每次进行GC时,都会对page进行压缩操作,所以没有碎片问题。虽然ZGC属于很新的GC技术, 但优点不一定真的出众,ZGC只在特定情况下具有绝对的优势, 如巨大的堆和极低的暂停需求。而实际上大多数开发在这两方面都不太成问题(尤其是在服务器端), 而对GC的性能/效率更在意。也有一种观点认为ZGC是为大内存、多cpu而生,它通过分区的思路来降低STW。

垃圾收集器分类

  • 串行收集器--->Serial和Serial Old,只能有一个垃圾回收线程执行,用户线程暂停。 适用于内存比较小的嵌入式设备 。
  • 并行收集器[吞吐量优先]--->Parallel Scanvenge、Parallel Old,多条垃圾收集线程并行工作,但此时用户线程仍然处于等待状态。 适用于科学计算、后台处理等若交互场景 。
  • 并发收集器[停顿时间优先]--->CMS、G1,用户线程和垃圾收集线程同时执行(但并不一定是并行的,可能是交替执行的),垃圾收集线程在执行的时候不会停顿用户线程的运行。 适用于相对时间有要求的场景,比如 Web 。

如何理解理解吞吐量和停顿时间

  • 停顿时间->垃圾收集器 进行 垃圾回收终端应用执行响应的时间
  • 吞吐量->运行用户代码时间/(运行用户代码时间+垃圾收集时间)

停顿时间越短就越适合需要和用户交互的程序,良好的响应速度能提升用户体验;高吞吐量则可以高效地利用CPU时间,尽快完成程序的运算任务,主要适合在后台运算而不需要太多交互的任务。

小结:这两个指标也是评价垃圾回收器好处的标准,其实调优也就是在观察者两个变量。

如何选择合适的垃圾收集器

  • 优先调整堆的大小让服务器自己来选择
  • 如果内存小于100M,使用串行收集器
  • 如果是单核,并且没有停顿时间要求,使用串行或JVM自己选
  • 如果允许停顿时间超过1秒,选择并行或JVM自己选
  • 如果响应时间最重要,并且不能超过1秒,使用并发收集器

如何开启需要的垃圾收集器

  • 串行 -XX:+UseSerialGC -XX:+UseSerialOldGC
  • 并行(吞吐量优先): -XX:+UseParallelGC -XX:+UseParallelOldGC
  • 并发收集器(响应时间优先) -XX:+UseConcMarkSweepGC -XX:+UseG1GC
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-04-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Java后端技术栈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 垃圾收集器
    • G1收集器
      • ZGC收集器
      • 如何理解理解吞吐量和停顿时间
      • 如何选择合适的垃圾收集器
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档