JVM背后发生了什么,垃圾回收如何影响Java性能?

性能调优世界是一个危险的地方,一个JVM标志失衡,事情很快就会变得繁琐。 因此 ,我们决定求助于Java性能调优专家, 单调 JVM探查器mjprof的创建者Haim Yadid 。 在这篇文章中,我们将分享他在实践中经受住考验的一些见解,并了解JVM内部在压力下的表现。

新帖:Java性能调优–如何充分利用垃圾收集器http://t.co/NnzQpuWBHz pic.twitter.com/8zqMrUfSHl

— Takipi(@takipid) 2015年4月2日

了解您要面对的问题

JVM受到垃圾收集暂停的影响,该暂停的频率和持续时间各不相同。 在暂停过程中,一切都停止了,各种意外行为开始发挥作用。 当面对一个新的调优项目时,通常会发生以下两种情况之一:公司已经知道它存在垃圾回收问题,或者很快就会发现它有一个问题。 在此阶段,他们很可能会遇到暂停,JVM卡住的不稳定行为以及性能普遍下降。 这些症状通常是通过响应时间慢,CPU和内存利用率高或系统在大多数情况下正常运行而具有不规则行为(例如,极其缓慢的事务和断开连接)而可见的。

主要陷阱:忽略异常值

可以通过一种常见的错误来忽略这种行为,并且不会向任何人发出警报,这是一个常见的错误:测量平均交易时间,并忽略异常值。 这就是GC问题隐藏的地方:尽管大多数情况下系统可能表现正常,但有时系统的响应能力却会下降,并给许多用户带来不良的体验。 例如,一个通常需要100毫秒的事务会受到GC暂停的影响,并突然花费几秒钟甚至一分钟。 在电子商务站点中,如果系统的维护人员仅查看平均交易时间,则除用户以外的任何人都不会注意到。 另一个容易被忽视的问题是,当系统吞吐量受到影响时(例如命中率达到20%),并且它无法充分发挥其潜力。 您可能永远不会知道出了什么问题,因为您没有查看正确的指标。 很多时候,原因是对GC开销的了解不足,并且只关注平均响应时间的一个指标,而忽略了第99个百分位数。

定义性能要求:频率和持续时间

这里的主要问题是:您认为应用程序中GC暂停频率和持续时间的可接受标准是什么? 例如,每天暂停15秒可能是可以接受的,而30分钟一次的频率对产品来说绝对是灾难。 这些要求来自每个系统的领域,在这些领域中,实时和高频交易系统将具有最严格的要求。

总体而言,看到15到17秒的停顿并不罕见。 某些系统甚至可能达到40-50秒的暂停,Haim也有机会在具有大量批处理工作的大堆的系统中看到5分钟的暂停。 因此,暂停持续时间在这里并不重要。

停止世界收集数据:GC日志的重要性

在基于HotSpot JVM的系统中,垃圾收集状态最丰富的数据源是GC日志。 如果您的JVM没有生成带有时间戳的GC日志,那么您就错过了用于分析和解决暂停问题的重要数据源。 这对于开发环境,登台,负载测试以及最重要的是在生产中都是如此。 您可以获取有关系统中所有GC事件的数据,无论这些事件是同时完成的还是引起世界停顿的:这些事件花费了多长时间,消耗了多少CPU以及释放了多少内存。 从这些数据中,您可以了解这些暂停的频率和持续时间,它们的开销,然后继续采取行动以减少它们。

-XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:mygclogfilename.gc

GC日志数据收集的最小设置

从指标来看,5%通常是可接受的GC开销的上限,而一个应用程序与另一个应用程序之间可接受的暂停时间却大不相同。

这里值得提及的两个用于GC日志分析的工具是Github上可用的开源GC Viewer和jClarity的Censum 。

解决方案策略

获得所需信息后,就可以检查可能的原因和解决方案了。 您进行的每项更改都要求进行一次新测试,并进行一轮日志收集,以评估其有效性并确定它是否有助于我们前进并达到要求。 优选在生产中和在压力下。 我们可以通过4种主要方法来解决由GC暂停引起的问题:切换垃圾收集器,调整控制Java堆的标志,更改代码以及使用其他JVM /收集器。 以下是对HotSpot领域中考虑的方法及其解决的问题类型的快速概述:

1.错误的垃圾收集器正在运行

粗略地说,JVM有4个垃圾收集器,您可以选择在启动期间使用哪个垃圾收集器。 要了解有关每种类型的更多信息,可以在此处查看比较。 GC问题的一个常见原因是针对您正在开发的应用程序类型使用了错误的收集器。 HotSpot的默认值是并行/吞吐量收集器,通常它不是您的应用程序的最佳选择。 选择正确的收集器的行为(通过JVM标志)是对系统优先级的声明,通常是要考虑的第一个问题。 通常,大多数并发的CMS和G1收集器将导致较少的暂停时间。 尽管出现暂停时,其持续时间可能会比Parallel收集器引起的持续时间长,因为其回退机制是单线程的(Ouch)。 另一方面,对于相同大小的堆,并行收集器将实现更高的吞吐量。 另一个准则与可预测性有关,如果可预测的性能是一个重要因素并且堆大小不大,那么并行收集器可能就是答案。 而且,如果平均响应时间/延迟是您的重中之重,则CMS或G1最有可能是答案。

2.调优Java堆

选择了首选的GC算法之后,该进行一些调整了。 测量(通过GC日志)吞吐量和暂停时间分布,如果您对此感到满意,那就完成了。 如果GC开销很高(并且吞吐量很低),通常增加堆大小将改善这种情况。 当要解决CMS或G1的长时间停顿时,情况就更加棘手。 造成碎片化的另一个原因是,JVM无法跟上对象从新一代迁移到旧一代的速度,然后需要暂停应用程序对其进行修复。 解决方案是更早启动GC或增加堆大小。

从经验来看,堆大小通常在1GB到8GB之间,而更大的堆则更为罕见。 在精简过程中,通常会在调整过程中将堆大小增加到8GB以上。 较大的堆大小的一个可行原因是,当我们想要创建一个大的缓存时,但这也可以在堆外解决。

让我们来看另一个示例,以说明需要调整溢出率的位置。 假设应用程序需要100MB的空间来处理某些请求,而新一代的大小为50MB。 不应该出现在旧一代中的对象将很快到达那里。 调整新世代和幸存者空间将需要解决这个问题,并确保短暂生命的物体将在新世代中终结它们的生命。 影响这里的主要因素是堆大小,新旧发电比,幸存者空间大小以及最大使用期限阈值–一个对象移动到旧发电需要多少GC周期。

我们需要考虑的另一个重要因素是应用程序的“实时设置”。 意味着长时间保留在内存中的对象的大小,例如,活动集的示例将是一个应用缓存,其中包含频繁的数据库查询结果集。 在调整JVM时,需要确保“ liveset”可以方便地容纳在旧版本中,并且除了消耗之外,该区域还具有足够的可用内存。 否则,将严重破坏JVM的行为,从而导致低吞吐量和频繁的暂停。

3.架构和代码更改

一些问题将迫使我们诉诸代码,甚至可能进行体系结构更改。 我们可以在此处解决的麻烦原因之一就是碎片化。 CMS收集器的长时间停顿可能是由旧一代的碎片导致的。 每个GC周期都会释放旧一代的内存块,使其看起来像瑞士奶酪,直到JVM 不能处理的时刻到来。 当JVM将来自新一代的对象移动到比这些“漏洞”更大的对象上,然后必须停止应用程序来解决问题时,就会发生这种情况。 状态随时间变化的应用程序必然会导致碎片化。 随着状态随着时间的推移而变化,“旧状态”对象将从旧版本中释放,而它们的替换状态在新一代中创建。 当它最终晋升为老一代时,它可能会不适用于正确的地方,这将导致碎片化。

对这类问题的体系结构解决方案可能是将对象更新到位,将“状态”移到堆外机制或拆分进程,对延迟敏感的关键路径,其中有许多短期分配的对象到一个进程,将大状态移到另一个进程一。

4.替代的JVM和垃圾收集器

如果暂停时间对您的应用程序至关重要,并且Hotspot JVM无法提供可接受的响应时间,则还有两个可能的选择。 第一个是具有不间断C4垃圾收集器的Azul Zing JVM 。 为了开始使用Zing,您将需要具有相对较大的计算机,并且堆大小必须从32GB开始。 另一个尚不成熟的选择,但如果您想生活在边缘,可能值得一试。这是Shenandoah GC算法。 它使用了一种称为布鲁克转发指针的技术,该技术导致超低的暂停时间和合理的开销。

进一步阅读:领先的GC专家

为了更深入地了解Garbage Collection和JVM的内部,以下是在GC领域中一些最有趣的人:

  • 查理·亨特 ( Charlie Hunt )是Oracle Java平台小组的成员,也是Java Performance一书的主要作者。
  • C4不间断垃圾收集器的创建者Azul Systems的首席技术官兼联合创始人Gil Tene 。
  • 性能调整和jClarity首席技术官兼联合创始人Kirk Pepperdine 。
  • Monica Beckwitt ,Java / JVM性能顾问。
  • Twitter的JVM / GC工程师Tony Printezis ,Oracle的前G1技术负责人。
  • Oracle的JVM开发人员Jon Masamitsu 。
  • Christine H. Flood和Roman Kennke ,Shenandoah GC算法的开发人员。

结论

垃圾回收是JVM中最引人入胜的主题之一,我们希望本文能帮助您更好地了解各个运动部件。 非常感谢Haim Yadid同意与我们分享他的经验! 如果您有任何疑问或想要澄清,请在下面的评论部分中告诉我们。

翻译自: https://www.javacodegeeks.com/2015/04/java-performance-tuning-getting-the-most-out-of-your-garbage-collector.html

Java性能调优:充分利用垃圾收集器相关推荐

  1. JVM性能调优2_垃圾收集器与内存分配策略__享学课堂

    判断对象的存活 引用计数法: 优点:快,方便,实现简单: 缺点:对象相互引用时,很难判断对象是否该回收. 可达性分析: 这个算法的基本思路就是通过一系列的称为"GC Roots"的 ...

  2. JVM性能调优3_垃圾收集器与内存分配策略__享学课堂

    Stop The World现象 GC收集器和我们GC调优的目标就是尽可能的减少STW的时间和次数. 内存分配与回收策略 对象优先在Eden分配,如果说Eden内存空间不足,就会发生Minor GC ...

  3. 为什么对 Java 性能调优最后都像在调 you?

    不知道你有没有发现,优化Java,或者任何其他语言的代码性能经常被当做是一种暗黑艺术. 性能分析有种神秘感.画面类似是这样的:一个「黑客」经过多年练就的手艺,能够快速深入了解某个系统,并提出神奇的解决 ...

  4. java必读书籍_最佳5本Java性能调优书籍–精选,必读

    java必读书籍 为什么Java开发人员应该阅读有关性能调优的书? 当我很久以前第一次面对这个问题时,我以为以后会做,但是我很长一段时间都没有回过头来. 仅当我在用Java编写的任务关键型服务器端财务 ...

  5. 最佳5本Java性能调优书籍–精选,必读

    为什么Java开发人员应该阅读有关性能调优的书? 当我很久以前第一次面对这个问题时,我以为以后会做,但是我很长一段时间都没有回过头来. 仅当我在用Java编写的任务关键型服务器端财务应用程序中遇到严重 ...

  6. 书籍:推荐两本java性能调优

    第一本:Java性能优化权威指南 Java性能优化圣经!Java之父重磅推荐! 本书由曾任职于Oracle/Sun的性能优化专家编写,系统而详细地讲解了性能优化的各个方面,帮助你学习Java虚拟机的基 ...

  7. 《Java性能调优实战》笔记(一)Java编程性能调优、多线程性能优化

    文章目录 一.Java性能调优概述 1.1 性能调优标准 1.2 制定性能调优策略 二.Java编程性能调优 2.1 字符串 2.2 正则表达式 2.3 ArrayList和LinkedList的选择 ...

  8. 还搞不懂性能调优?让你见识这份《Java性能调优PDF》啃完你就知道多厉害了!

    Java 应用性能优化是一个老生常谈的话题,典型的性能问题如页面响应慢.接口超时,服务器负载高.并发数低,数据库频繁死锁等.尤其是在"糙快猛"的互联网开发模式大行其道的今天,随着系 ...

  9. java 性能调优_Java性能调优调查结果(第四部分)

    java 性能调优 这是本系列中的最后一篇文章,我们将分析我们在2014年10月进行的Java Performance Tuning Survey的结果.如果您尚未阅读第一篇文章,建议您首先阅读以下内 ...

最新文章

  1. docker from指令的含义_Docker中Dockerfile多From 指令存在的意义
  2. 使用 GetStartupInfo 检查自己是否被调试
  3. Hibernate修改命名策略
  4. Activity内嵌Fragment,当Activity recreate时Fragment被添加多次,造成相互遮盖
  5. js php 时间格式化字符串,JS怎么实现字符串与日期的互相转换及日期的格式化
  6. cad2016珊瑚_预测有马的硬珊瑚覆盖率
  7. python启动http服务_Python通过命令开启http.server服务器的方法
  8. HTTP和HTTPS的理解
  9. java 回调函数的写法
  10. 手机计算机都无法上网,手机能上网但win7电脑不能上网怎么回事?
  11. 货效,坪效,人效,这三效怎么理解?
  12. BZOJ1863 [ZJOI2006]trouble 皇帝的烦恼 [思维题,二分答案,动态规划]
  13. 【小程序】微信小程序开发技巧实用手册(自己做笔记用)
  14. 介绍两个用于生成二维码的js库
  15. 发布会直播平台哪家好
  16. 企业级网络架构—云平台高可用网络的修炼之道
  17. ThinkPad E40取消FN功能键设置
  18. 【求助】ipad远程桌面下vmware键盘布局错乱
  19. ReentrantReadWriteLock读写锁(读多写少场景)
  20. 小数分频锁相环中的整数边界杂散IBS

热门文章

  1. Feign数据压缩传输
  2. SpringBoot运行原理初探
  3. json vs obj
  4. mysql---批量插入数据:100w条数据
  5. docker 买了腾讯服务器后的学习
  6. 2015c语言9月答案,2015年9月计算机二级C语言预测题答案
  7. python定义函数prime判断是否是素数_用自定义函数判断素数 用C语言编写自定义函数prime(int x),判断x是否为素数?...
  8. selenium自动化测试_Selenium测试可实现有效的测试自动化
  9. stomp java客户端_Stomp-Spring服务器端的Web套接字Java客户端
  10. 2018年4月13日_Java的最新发展– 2018年4月下旬