分析GC优化结果
在设置了GC参数以及-verbosegc参数之后,通过tail命令确保日志被正确的生成。如果参数设置的不正确或者日志没有生成,你将白白浪费你的时间。如果日志正确的话,持续收集1到2天。随后最好将日志下载到本地PC并用HPJMeter来分析
- Full GC 执行时间
- Minor GC执行时间
- Full GC 执行间隔
- Minor GC 执行间隔
- Entire Full GC 执行时间
- Entire Minor GC 执行时间
- Entire GC 执行时间
- Full GC e执行时间
- Minor GC 执行时间
找到最佳的GC参数是件非常幸运的事情,然而在大多数场合,我们并不会得到幸运之神的眷顾,在进行GC优化时要尽量小心谨慎,想一步完成优化往往会导致OutOfMemoryError 。
优化示例
好了,我们一直在纸上谈兵,现在我们看一些实际的GC优化的例子。
示例1
下面这个例子针对 Service S的优化,对于最近被部署的 Service S,Full GC花费了太长的时间。
请看 jstat –gcutil的执行结果。
1
2
|
S0 S1 E O P YGC YGCT FGC FGCT GCT 12.16 0.00 5.18 63.78 20.32 54 2.047 5 6.946 8.993 |
最左边的Perm 空间对于最初的GC优化不是很重要,这一次YGC参数的值更加有用。
Minor GC和Full GC的平均值如下表所示
表3:Service S的Minor GC 和Full GC的平均执行时间
GC 类型 |
GC 执行次数 |
GC 执行时间 |
平均 |
Minor GC |
54 |
2.047 |
37 ms |
Full GC |
5 |
6.946 |
1,389 s |
最重要的是下面两个数据
- 新生代实际使用空间: 212,992 KB
- 老年代实际使用空间: 1,884,160 KB
因此,总的内存空间为2GB,不算Perm空间的话,新生代与老年代之比为1:9。通过jstat和-verbosegc 日志进行数据收集,并把三台服务器按照如下方式设置。
- NewRatio=2
- NewRatio=3
- NewRatio=4
一天之后,检查系统的GC日志后发现,在设置了NewRatio参数后很幸运的没有发生Full GC,
为什么?
- NewRatio=2: 45 ms
- NewRatio=3: 34 ms
- NewRatio=4: 30 ms
我们看到NewRatio=4 是最佳的参数,虽然它的新生代空间最小,但GC时间确最短。设定这个参数之后,系统没有执行过Full GC。
为了说明这个问题,下面是服务之星一段时间后执行jstat –gcutil的结果
1
2
|
S0 S1 E O P YGC YGCT FGC FGCT GCT 8.61 0.00 30.67 24.62 22.38 2424 30.219 0 0.000 30.219 |
你可能会认为因为服务器接受的请求少才导致的GC执行频率下降。实际上,虽然Full GC没有执行,但是Minor GC被执行了 2,424次。
示例2
这是一个针对ServiceA的例子,我们通过公司内部的应用性能管理系统(APM)发现JVM暂停了相当长的时间(超过8秒),因此我们进行了GC优化。我们找到了Full GC执行时间过长的原因,并着手解决。
进行GC优化的第一步,就是我们添加了-verbosegc参数,并得到如下结果。
图1:进行GC优化之前的STW时间
如上图所示,由HPJMeter自动生成的图片之一。X坐标表示JVM执行的时间。Y坐标表示每次GC的时间。CMS绿点,表示Full GC结果。Parallel Scavenge蓝点,表示Minor GC结果。
之前我曾经说过CMS GC是最快的,但是上面的的结果显示出于某种原因,它最多花费了15秒。是什么导致这个结果?是否想起我之前提过的,CMS在进行内存清理时,会变慢。与此同时,服务的内存被设定为 –Xms1g和–Xmx4g ,且实际分配了4GB内存。
因此,我将GC类型从CMS改为Parallel GC。并且将内存改为2GB,设定NewRatio 为3。几小时之后我使用 jstat –gcutil得到如下结果
1
2
|
S0 S1 E O P YGC YGCT FGC FGCT GCT 0.00 30.48 3.31 26.54 37.01 226 11.131 4 11.758 22.890 |
相对于4GB时的15秒,Full GC变成了平均每次3秒。但是3秒一样比较慢,因此我设计了如下6种场景。
- Case 1: -XX:+UseParallelGC -Xms1536m -Xmx1536m -XX:NewRatio=2
- Case 2: -XX:+UseParallelGC -Xms1536m -Xmx1536m -XX:NewRatio=3
- Case 3: -XX:+UseParallelGC -Xms1g -Xmx1g -XX:NewRatio=3
- Case 4: -XX:+UseParallelOldGC -Xms1536m -Xmx1536m -XX:NewRatio=2
- Case 5: -XX:+UseParallelOldGC -Xms1536m -Xmx1536m -XX:NewRatio=3
- Case 6: -XX:+UseParallelOldGC -Xms1g -Xmx1g -XX:NewRatio=3
那一个最快呢?结果显示,内存越小,结果越好。下图展示了Case6的结果。这是GC的性能最好。最长的响应时间只有1.7秒。平均时间在1秒之内。
图2:Case6的时间图表
基于以上结果。我们按照Case6调整了GC参数。但是,这导致了每天晚上都会发生OutOfMemoryError。在这里很难解释具体的原因。简单来说,批处理程序导致了内存泄漏。相关的问题已经被解决。
如果对GC日志只分析很短的时间就贸然对所有服务器进行优化是非常危险的。请时刻牢记,你必须同时分析GC日志和应用程序。
我们回顾了两个关于GC优化的例子,正如我之前提到的,例子中提到的GC参数,可以设置在相同的服务器之上,但前提是他们具有相同的CPU,操作系统,JDK版本以及运行着相同的服务。但是不要直接把我用过的参数用到你的服务至上,它们未必能很好的工作。
结论
我凭借经验进行GC优化,而没有执行堆转储并分析内存的详细内容。精确地分析内存可以得到更好的优化效果。但是,这种分析一般适用于内存使用量相对固定的场合。不过,如果服务严重过载并占用的大量的内存,强力建议根据之前的经验进行GC优化。
我已经在一些服务上设置了G1 GC参数,并进行过性能测试。但还没有应用与正式环境,G1 GC参数的速度要快于其他任何GC类型。但是,你必须要升级到JDK7。另外,他的稳定性也暂时没有保障,没人知道是否会出现致命的错误。因此还不到将其正式应用的时候
在未来的某一天,等到JDK7真正稳定了(这不是说他现在不稳定),并且WAS针对JDK7进行优化后,G1 GC最终能够按照预期的那样工作了,我们可能就不需要在进行GC优化了。
想了解GC优化的更多内容,请登录Slideshare.com 查看关联资源。强烈推荐Everything I Ever Learned About JVM Performance Tuning @Twitter。作者Attila Szegedi,一位Twitter工程师。请花些时间阅读。
By Sangmin Lee, NHN Performance Engineering Lab.
作者Sangmin Lee,就职于NHN性能工程研究院
译文地址: http://www.importnew.com/3146.html
【如需转载,请在正文中标注并保留原文链接、译文链接和译者等信息,谢谢合作!】
相关推荐
Java垃圾回收机制是Java编程语言的关键特性之一,它自动化地管理程序运行时的内存,确保程序不会因内存泄漏而崩溃。垃圾回收(GC)的主要目标是识别并清理不再被程序中任何活动对象引用的对象,从而释放内存资源。...
Java垃圾回收机制是Java编程中的核心概念,它自动管理程序中的内存分配与释放,从而避免了程序员手动管理内存可能导致的内存泄漏等问题。垃圾回收的主要任务是识别并清理不再被程序引用的对象,释放其所占用的内存...
Java垃圾回收机制是Java语言的一大特性,它负责自动管理程序中的内存,避免了程序员手动进行内存释放,从而降低了出现内存泄漏等问题的风险。垃圾回收的主要任务是识别并清理那些不再被程序引用的对象,以便回收它们...
总之,理解并掌握Java垃圾回收机制对于编写高效、稳定的Java程序至关重要。通过实践和调整,我们可以有效地利用内存资源,提高应用的运行效率。在实际项目中,选择合适的垃圾回收器和调优策略是提升系统性能的关键。
Java垃圾回收机制是Java语言中的一个重要特性,它自动管理程序中的内存,避免程序员手动处理内存释放,从而减少了内存泄露和程序崩溃的风险。垃圾回收的主要目标是识别并清理不再被程序引用的对象,以便回收其占用的...
Java垃圾回收机制是Java虚拟机(JVM)中至关重要的组成部分,它的主要任务是自动管理内存,回收不再使用的对象以避免内存泄漏。垃圾回收机制在Java中自动化了内存管理,使得程序员无需手动管理内存,降低了编程复杂...
Java垃圾回收机制是Java编程语言中的一项核心特性,它负责自动管理程序中的内存分配和释放,以避免内存泄漏和资源浪费。在Java中,程序员无需手动进行内存管理,因为垃圾回收器会识别并清理不再使用的对象,从而释放...
Java垃圾回收机制是Java编程语言中的一个重要特性,它负责自动管理程序中的内存,避免程序员手动进行繁琐且容易出错的内存释放操作。垃圾回收的主要目标是识别并清理那些不再被程序使用的对象,以释放内存资源。以下...
在"java垃圾回收机制介绍.doc"文档中,可能还会深入讨论如何监控和调试垃圾回收,包括使用JConsole、VisualVM等工具,以及分析GC日志,以理解垃圾回收的性能和行为,从而优化应用程序的内存使用。 了解和掌握Java...
Java垃圾回收机制是Java虚拟机(JVM)内存管理的关键组成部分,主要负责自动释放不再使用的对象,从而避免内存泄漏并优化内存使用。垃圾回收在Java中自动进行,程序员无需手动管理内存,这使得开发更加简便,同时...
总之,监控Java垃圾回收是一个复杂但必要的过程,需要综合运用各种工具、技术和实践经验。通过深入理解GC的工作原理,调整合适的GC策略,以及优化代码,开发者可以提升应用的性能和稳定性,成为一名真正的Java GC...
Java垃圾回收(Garbage Collection, 简称GC)是Java虚拟机(JVM)管理内存的一种机制,它自动地识别并清理不再使用的对象,从而避免了程序员手动管理内存可能导致的内存泄漏问题。垃圾回收是Java语言的一个重要特性...
理解并掌握Java垃圾回收机制,不仅有助于解决内存溢出、性能瓶颈等问题,还能在面试中展现对Java内存管理的深入理解。对于开发者来说,熟练运用各种GC算法和收集器,以及掌握调优技巧,是提升代码质量和系统性能的...
Java虚拟机(JVM)的垃圾回收(GC)机制是Java程序高效运行的关键部分,它自动管理内存,释放不再使用的对象以避免内存泄漏。本文主要探讨JVM堆内存的结构和GC的工作原理,以及如何进行性能调优。 JVM堆是Java应用...
在Java编程语言中,垃圾回收(Garbage Collection, GC)是...本压缩包中的文件可能涵盖了这些主题的详细讲解,包括理论知识、实践案例和性能调优技巧,对于希望深入理解Java垃圾回收机制的开发者来说是一份宝贵的资料。
Java的垃圾回收机制是由虚拟机(JVM)的一部分——垃圾回收器(Garbage Collector)来执行的。与C++等语言不同,Java程序员不需要显式地释放内存,这大大减少了内存泄漏的可能性。 垃圾回收器通过一系列算法来判断...
本文将对Java垃圾回收进行小结,探讨其基本原理、类型以及常见算法。 1. 基本原理: Java中的内存分为堆(Heap)和栈(Stack)两部分,垃圾回收主要关注堆内存。当一个对象不再被任何引用指向时,它被视为可回收的...
### JAVA垃圾回收个人总结 #### 一、垃圾回收(GC)概述 垃圾回收(Garbage Collection,简称GC)是Java虚拟机(JVM)提供的一种自动内存管理机制,它负责自动回收不再使用的对象所占用的内存空间,从而避免了手动管理...