摘要
本文记录GC调试的一次实验过程和结果。
GC知识要点回顾
问题1:为什么要调试GC参数?
在32核处理器的系统上,10%的GC时间导致75%的吞吐量损失。所以在大型系统上,调试GC是以小博大的不错选择。'small improvements in reducing such a bottleneck can produce large gains in performance.'
在32核处理器的系统上,10%的GC时间导致75%的吞吐量损失。所以在大型系统上,调试GC是以小博大的不错选择。'small improvements in reducing such a bottleneck can produce large gains in performance.'
问题2:怎么样调试GC?
调试GC,有三个主要的参数:
- 选择合适的GC Collector
- 整个JVM Heap堆的大小
- Young Generation的大小(-Xmn?m or -XX:NewRatio=?)
问题3:有哪些不同的GC Collector?
Tony Printezis (JVM大牛)在Garbage Collection in the Java HotSpot Virtual Machine有图为证,还有一篇更早的sun开发人员介绍GC调试也是有图为证
neo4j总结如下
Copy |
Young |
|
The Copying collector |
MarkSweepCompact |
Tenured |
|
The Mark and Sweep Compactor |
ConcurrentMarkSweep |
Tenured |
|
The Concurrent Mark and Sweep Compactor |
ParNew |
Young |
|
The parallel Young Generation Collector — can only be used with the Concurrent mark and sweep compactor. |
PS Scavenge |
Young |
|
The parallel object scavenger |
PS MarkSweep |
Tenured |
|
The parallel mark and sweep collector |
简而言之,Young和Tenured各种三种Collector,分别是
- Serial 单线程
- Parallel 多线程并行, GC线程和App线程取一运行,即GC要Stop the (app) world。
- Concurrent 多线程并发,GC线程和App线程可同时运行。(注: Young generation 没有CMS,取而代之的是可和CMS(Old)一起运行的ParNew)
问题4:如何选择Collector?
Serial可以直接排除掉,现在最普通的服务器也有双核64位\8G内存,默认的Collector是PS Scavenge和PS MarkSweep。所以Collector在并行(Parallel)和并发(Concurrent)两者之间选择。
问题5:选择的标准(参数指标)是什么?如何得到这些参数值(How to measure it)?
throughput和latency。garbage-collection-in-java-part-3从GC的耗时给出了吞吐量和响应速度的公式
Total Execution Time = Useful Time + Paused Time
throughput = Useful Time / Total Execution Time
latency = average paused time
如何得到Useful time 和 Paused Time?即如何得到JVM的GC时间,有以下几种方式
GC Log
打印GC log,java 启动参数中加入下面的语句(本文为tomcat应用)。GC Log 记录每次GC时间,可根据GC Log计算平均GC时间和累积GC时间。
- CATALINA_OPTS="$CATALINA_OPTS -verbose:gc -Xloggc:/usr/local/tomcat/gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps"
JDK自带工具,java 启动参数中加入下面的语句(本文为tomcat应用),然后在监控端可以远程连接1090端口。在内存一项,有累积GC时间和次数。注意在以min为单位显示时,只显示整数部分,如1min20s显示为1min。
- CATALINA_OPTS="$CATALINA_OPTS -Dcom.sun.management.jmxremote.port=1090 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false"
JVM监控工具,未同JDK一起发布,可在JVisualvm(JDK自带)中以插件的方式使用,本文为独立使用。有累积GC时间和次数,并有曲线图直观显示。
首先在Server端启动jstatd
- vi jstatd.all.policy
- grant codebase "file:${java.home}/../lib/tools.jar" {
- permission java.security.AllPermission;
- };
- jstatd -J-Djava.security.policy=jstatd.all.policy
然后在监控启动VisualGC,远程连接服务端进程id
visualgc 102592@remote.domain
问题5:应用请求的吞吐量和响应是否可以反映JVM的性能?
正是我们调优的目标。本文使用Jmeter来做压力测试,并给出吞吐量和响应 report。
测试
硬件环境
|
|
Test case
- 使用用Jmeter压力测试
- 共6个client,每个client启动30个线程发送请求
- 每个请求从16种测试样例中随机挑选一个,发送到server端
- 测试持续10min
参数值
- server使用默认GC(PS Scavenge和PS MarkSweep)
- server使用CMS(-XX:+UseConcMarkSweepGC-XX:+UseParNewGC)
- server使用CMS(-XX:+UseConcMarkSweepGC -XX:+UseParNewGC),设置Young generation的大小为200m(-Xmn200m)
- server使用CMS(-XX:+UseConcMarkSweepGC -XX:+UseParNewGC),设置Young generation的大小为600m(-Xmn600m)
观察值
- Jmeter请求的summary report
- server端累积GC时间和次数
测试结果
1) CMS和Parallel比较
1.1) 吞吐量和响应
(PS Scavenge和PS MarkSweep)
(ParNew和CMS)
从Jmeter的report中可以看出, 使用CMS后吞吐量(对应总的请求数)下降18%,而最大响应时间(包括最小响应时间)有近30%的提升(变小)。这验证了Tony Printezis在Step-by-Step:Garbage Collection Tuning in the Java HotSpot™ Virtual Machine中说使用CMS应用的吞吐量会相对下降,但有更好的最差响应时间。
-
Expect longer young GC times
- Due to slower allocations into the old gen
-
Expect better worst-case latencies
- CMS does its work mostly-concurrently
- Shorter worst-case pauses
-
Expect lower throughput
- CMS does more work
在官方的JVM性能调优中给出的建议也是,如果你的应用对峰值处理有要求,而对一两秒的停顿可以接受,则使用(-XX:+UseParallelGC);如果应用对响应有更高的要求,停顿最好小于一秒,则使用(-XX:+UseConcMarkSweepGC)。
1.2) GC 累积时间和次数
(PS Scavenge和PS MarkSweep)
(ParNew和CMS)
PS累积GC时间(visualgc)为1min25s,其中Eden 189次,共52s;old 13次,共33s。
CMS 累积GC(visualgc)为2min2s,其中Eden 2333次,共1min46s;old 55次,共16s。(Jconsole和GC log却显示没有Full GC,从understanding cms gc logs和jstat显示的full GC次数与CMS周期的关系中我推测visualgc与jstat显示一致,都是统计old的回收次数;而Full GC则是Young和Old一起回收,在其他类型的GC里,Old只有Full GC时才触发)。
可以看到PS的GC频率相对低,但每次GC时间长,每次Full在3s左右徘徊,Yong在0.3s左右;CMS则是短频快,频繁快速回收,yong在0.03s(<0.1s)左右,old<0.5s。从JMeter上,使用PS GC,Request Report会有间歇性的停顿,即server没有任何响应;CMS则相对较少,停顿不那么明显。
2) CMS下不同Xmn的比较
由于CMS Young太多频繁,又测试了分别调整Xmn为200m和600m之后的结果。200m是仿照cassandra中100m * cpu #来设置Young gen的大小;600m则是与PS下的Young gen一致。
200m
600m
随着Young gen的增大(40m -> 200m -> 600m),Young 的回收次数减少,Old的回收次数增加,总体GC累积时间下降,应用吞吐量上升,最差响应时间变慢(即便和PS比较也更差,是我的测试有问题?)。
结论
app停顿3s是不可接受的,因此倾向于使用CMS;CMS的default young gen相当小,于是设置Xmn。对于更加Prefer响应的应用,下面配置是否是黄金标配:
JVM_OPTS="$JVM_OPTS -XX:+UseParNewGC"
JVM_OPTS="$JVM_OPTS -XX:+UseConcMarkSweepGC"
JVM_OPTS="$JVM_OPTS -XX:+CMSParallelRemarkEnabled"
JVM_OPTS="$JVM_OPTS -XX:SurvivorRatio=8"
JVM_OPTS="$JVM_OPTS -XX:MaxTenuringThreshold=1"
JVM_OPTS="$JVM_OPTS -XX:CMSInitiatingOccupancyFraction=75"
JVM_OPTS="$JVM_OPTS -XX:+UseCMSInitiatingOccupancyOnly"
相关推荐
Java垃圾收集(Garbage Collection, 简称GC)是Java编程中的一项重要特性,它自动管理内存,释放不再使用的对象,避免了程序员手动管理内存可能导致的内存泄露问题。本篇将深入探讨Java中的GC过程。 一、Java内存...
Java GC与性能调优 Java GC与性能调优是 Java programming language 中非常重要的一部分,直接影响着 Java application 的性能。本文档将对 Java GC 与性能调优进行详细的介绍。 一、 Java 平台的逻辑结构 Java ...
### Java GC垃圾回收调优指南 #### 概述 在Java开发过程中,垃圾回收(Garbage Collection, GC)是管理内存资源的关键技术之一。合理的GC配置可以显著提高应用程序的性能和稳定性。本指南旨在帮助开发者深入理解...
GC java 手册 kindle格式 GC java 手册 kindle格式 GC java 手册 kindle格式
### Java GC工作原理详解 #### 一、引言 在现代软件开发中,Java作为一种广泛使用的编程语言,其强大的功能和高效性深受开发者喜爱。Java的自动内存管理机制是其一大亮点,尤其体现在垃圾收集(Garbage Collection...
针对“摄像头gc2385代码调试”这个主题,我们主要关注的是MTK6739平台上的摄像头传感器GC2385的驱动程序开发与调试。MTK6739是由联发科(Mediatek)制造的一款四核处理器,常用于入门级和中低端智能手机,而GC2385则...
此外,JDK提供了丰富的工具来帮助分析和调试GC行为,如`jconsole`、`jvisualvm`和`jmap`等。例如,`jstat`可以实时监控GC的状态,而`jhat`可以分析堆转储文件,找出内存泄漏的线索。 在实际开发中,Java程序员可以...
Java垃圾收集(GC)专题针对的是Java编程语言中内存管理机制的重要组成部分。Java自1996年推出以来,其最大的改进之一就是引入了受管内存。在Java之前,C和C++语言中的内存泄漏问题十分常见,这导致开发稳定和安全的...
在Java编程语言中,垃圾回收(Garbage Collection, GC)是一项至关重要的机制,它自动管理内存,释放不再使用的对象,防止内存泄漏。本篇将深入探讨如何监控Java的垃圾回收,帮助开发者提升应用性能和稳定性。 Java...
【Java GC机制详解】 Java垃圾回收(Garbage Collection, GC)是Java虚拟机(JVM)的核心特性之一,它负责自动管理程序运行时的内存,有效地避免了内存泄露和溢出的问题。Java GC机制主要涉及以下几个关键方面: 1...
Java虚拟机(JVM)是Java程序运行的基础,它的配置参数和垃圾收集(GC)机制对于优化应用程序性能至关重要。本文将深入探讨JVM参数及其与Java垃圾收集相关的知识。 一、JVM参数详解 JVM参数可以分为三类:启动参数...
在电子-gc0308调试.zip这个压缩包文件中,我们主要关注的是与单片机和嵌入式系统相关的知识,特别是STM32系列微控制器的使用,具体包括F3、F4、F7以及H7这四个不同的内核版本。STM32是由意法半导体...
Java虚拟机(JVM)是运行Java字节码的虚拟机进程。它负责在不同操作系统上...以上就是对JavaGC专家指南中提到的知识点的一个全面解析,涵盖了从虚拟机的基本概念到内存管理,再到垃圾回收和性能调优的各个重要方面。
Java内存区域和垃圾收集(GC)机制是Java编程中至关重要的一部分,它关乎程序的性能、稳定性和资源管理。本文将深入探讨Java虚拟机(JVM)中的内存划分、垃圾收集的工作原理以及相关工具的使用。 1. **Java内存区域...
【Java GC on HP-UX Itanium】和【JDK on HP-UX 简要介绍及性能调试概要】这两个主题涉及到的是Java在HP-UX操作系统上的运行环境、内存管理和性能优化,特别是针对Itanium架构的Java垃圾收集(GC)机制。以下是详细...
《GCViewer:深入理解Java垃圾收集日志分析与监控》 在Java开发中,内存管理和垃圾收集是至关重要的环节,不当的内存管理可能导致系统性能下降甚至出现应用崩溃。GCViewer是一款强大的工具,专用于分析和监控Java...
在第一篇文章成为JavaGC专家PartI—深入浅出Java垃圾回收机制中我们学习了不同GC算法的执行过程,GC如何工作,新生代及老年代的基本概念,在JDK7中你应该了解的5种GC类型以及他们的性能如何。在第二篇文章成为JavaGC...