垃圾收集器很大程度上会影响应用的吞吐量和延迟。在调优之前,首先要监控,继而进行分析。那我们先看一下如何获取GC数据,并理解这些数据。
获取GC数据
可以在命令行中指定下面一种选项:
- -verbose:gc或-verbosegc
- -XX:+PrintGCDetails——获取的信息比-verbose:gc更多
如果要获取GC执行的时间,计算GC的持续时间和频率,可以在命令行中指定任一选项:
- -XX:+PrintGCTimeStamps——显示从JVM启动到执行GC时流逝的时间,单位是秒
- -XX:+PrintGCDateStamps——显示执行GC时的本地时间(Java 6 update 4才开始支持)
要想观察GC的开销,或者看应用的延迟是应用本身的延迟,还是JVM GC的stop-the-world阶段的开销,可以指定-XX:+PrintGCApplicationConcurrentTime和-XX:+PrintGCApplicationStoppedTime选项。
另外还可以使用-Xloggc:<fileName>选项将GC数据直接输出到文件中,以便进行离线分析。
输出示例
常规输出
下面是Java 7 update 71(不同版本的输出可能会略有不同)上使用-XX:+PrintGCDetails获取的输出示例:
22.435: [Full GC [PSYoungGen: 638K->0K(36352K)] [ParOldGen: 8507K->9082K(44032K)] 9146K->9082K(80384K) [PSPermGen: 14392K->14392K(21504K)], 0.0547773 secs] [Times: user=0.08 sys=0.00, real=0.06 secs]
第一条信息:
GC说明是minor GC(年轻代GC)。
PSYoungGen表示收集使用的收集器是多线程垃圾收集器Parallel Scavenge。
1151K->638K(36352K)中,1151K表示收集前年轻代占用的内存,638K表示收集后年轻代占用的内存。由于年轻代分为Eden和两个Suvivor,minor收集后Eden为空,所以该值也是Survivor的占用量。括号中的36352K是年轻代的大小。
9659K->9146K(80384K)中,9659K表示收集前整个堆占用的内存,9146K表示收集后整个堆占用的内存。括号里的80384K是Java堆的总量,可以算出老年代的大小是44032K(80384K-36352K)。
0.0032716是整次GC的暂停时间。
[Times: user=0.03 sys=0.00, real=0.00 secs]里,user是垃圾收集器执行非操作系统调用指令所耗费的CPU时间,sys是垃圾收集器执行操作系统调用所耗费的CPU时间, real表示完成GC的实际时间。
GC之后,年轻代减少了513K(1151K-638K),老年代占用的空间则没有变化((9146K-638K)-(9659K-1151K)),这说明年轻代里的对象都被回收了,没有晋升到老年代中。
第二条信息:
Full GC说明是full GC,是对整个堆进行GC,包括年轻代、老年代和永久代。
PSYoungGen: 638K->0K(36352K)的含义和第一条信息里的PSYoungGen: 1151K->638K(36352K)一样。
ParOldGen: 8507K->9082K(44032K)表示老年代收集使用的是多线程垃圾收集器Parallel Old,收集前老年代占用8507K,收集后占用9082K,老年代的大小是44032K。
PSPermGen: 14392K->14392K(21504K)说明GC前永久代的占用量是14392K,GC后永久代的占用量是14392K,而永久代的大小是21504K。
带延迟信息的输出
下面是Java 7 update 71上使用-XX:+PrintGCDetails和-XX:+PrintGCApplicationConcurrentTime、-XX:+PrintGCApplicationStoppedTime选项获取的输出示例:
21.719: [GC [PSYoungGen: 1815K->64K(15360K)] 10319K->8567K(49664K), 0.0035923 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
21.723: [Full GC [PSYoungGen: 64K->0K(15360K)] [ParOldGen: 8503K->8523K(34304K)] 8567K->8523K(49664K) [PSPermGen: 14392K->14392K(22016K)], 0.0500793 secs] [Times: user=0.12 sys=0.00, real=0.05 secs]
21.773: Total time for which application threads were stopped: 0.0542506 seconds
在这个片段中,应用运行了1.83秒,GC用了0.054秒,此次GC大约有3%的开销。
显式GC
如果GC输出信息中包含(System),那说明这次GC是应用显式调用System.gc()所引起的。Java通常不建议应用进行显式的垃圾收集,要是在GC输出中发现该信息,就需要调查代码显式GC的原因了。
[Full GC (System) [PSYoungGen: ......
小结
通常来说,如果minor GC时,年轻代里的对象大部分被晋升到了老年代,被GC的并不多,那可以说明年轻代太小了。但在minor GC前后,老年代的大小要是没有发生变化,那意味着没有对象从年轻代提升到老年代。这是个好现象,说明minor GC回收了较多的垃圾对象,可以减少full GC的频率(full GC的持续时间很长)。
如果日志里只有full GC,每次full GC后,老年代几乎没回收什么空间,而且年轻代总有很大的占用量,那很可能是老年代空间不够大。
GC调优就基于对数据的分析,以及应用追求的性能指标(吞吐量、延迟、抑或内存占用),然后调整相应的设置,再进行新一轮的“监控——分析——调优”,……,直到满足应用的性能指标。
相关推荐
5. **内存泄漏检测**:虽然GCViewer本身不直接检测内存泄漏,但通过对长时间内内存占用持续增长的趋势分析,可以间接提示可能存在的问题。 总之,GCViewer是Java开发者必备的工具之一,它为我们提供了深入理解JVM...
总的来说,通过`jstat`和GC日志,我们可以深入理解Java进程的内存行为,定位并解决频繁GC的问题,从而提高应用性能。记住,优化JVM配置是一项细致的工作,需要根据具体应用的特性进行调整,不能一概而论。
理解GC** GC(Garbage Collection),即垃圾收集,是Java虚拟机(JVM)的一项关键特性,用于自动回收不再使用的对象所占用的内存空间,防止内存泄漏的发生。在JVM中,存在多种GC算法: - **串行GC(Serial GC)**:...
"用于测试jvm gc调优-share-jvm-gc.zip"这个压缩包文件很可能包含了一些工具、脚本或教程,用于帮助我们了解和实践JVM的垃圾收集优化。 首先,我们需要理解JVM GC的基本原理。垃圾收集器的主要任务是识别并回收不再...
- **设置GC策略**:如 `-XX:+UseParallelGC` 选择并行GC,`-XX:+UseG1GC` 选择G1垃圾收集器。 - **避免Full GC**:通过 `-XX:MaxTenuringThreshold` 控制对象晋升老年代的阈值。 - **监控和诊断**:使用 `-XX:+...
"jvm-full-gc.zip"这个压缩包很可能包含了关于JVM全GC(Full GC)的相关示例和资料,用于帮助理解JVM的内存管理和垃圾回收机制。 全GC(Full GC)是JVM进行垃圾回收的一种模式,主要涉及堆内存(包括年轻代和老年代...
在JDK8中,G1垃圾收集器成为了一种常用的选择,其参数如`-XX:G1HeapRegionSize` 设定G1区域的大小,`-XX:G1ReservePercent` 预留一部分内存以降低内存溢出的风险,`-XX:G1MixedGCCountTarget` 控制混合收集的频率。...
例如,`-Xlog:gc*=debug:file=gc.log` 参数可以开启详细的GC日志输出。 总之,【JAVA·初级】GC垃圾回收机制是Java开发者必须掌握的基础知识,深入理解和运用GC机制,能有效提升程序的性能和稳定性。在实践中不断...
以上参数是JDK10中GC调优的关键,理解并合理使用这些参数能够帮助开发者优化应用的内存管理,提升性能并降低暂停时间。在实际应用中,应根据具体应用的负载、内存需求以及性能目标来调整这些参数。
GC调优是一个复杂的过程,涉及多个方面,包括选择合适的GC算法(如CMS、G1、ZGC等)、调整堆大小、新生代与老年代的比例,以及对象存活率等。通过activemq-gc-plugin,你可以获得更详细的GC信息,为调优提供数据支持...
本文将详细介绍Java 7中常见的垃圾回收器和相应的JVM参数,帮助读者更好地理解和使用这些参数进行性能调优。 垃圾回收器是JVM用来释放不再使用的对象所占用内存空间的机制,主要包括: 1. Serial(串行)回收器:...
面试中,对Java平台的理解不仅包括语言特性和基础类库,如集合框架、输入/输出(IO/NIO)、网络编程、多线程、安全等,还涉及到JVM的深入理解。比如,Java的类加载机制,包括Bootstrap、Application和Extension ...
- **GC策略优化**:根据gchisto的输出调整GC参数,如新生代大小、老年代大小、GC算法等,以达到最佳性能。 4. **案例分析** - **频繁Full GC**:如果观察到Full GC次数过多,可能需要增大老年代空间,或者调整GC...
10. **JVM日志和GC日志**:通过`-XX:+PrintGCDetails`和`-XX:+PrintGCDateStamps`等参数,可以输出详细的GC事件信息,帮助分析GC行为。 调优是一个持续的过程,需要根据应用的特性和负载情况来选择合适的垃圾收集器...
- **使用工具监控GC**:监控垃圾收集器的行为,分析GC日志,理解GC对应用性能的影响。 - **代码层面的优化实践**:比如在使用Netty进行SSL性能调优时,下载对应的小版本进行优化。 - **合理利用JDK参数**:通过设置...
在描述中的例子中,尽管每次调用`System.gc()`时并未立刻看到垃圾回收的发生,但随后出现了垃圾回收信息的输出,这可能是因为JVM内部的工作机制。JVM通常会维护多个垃圾回收线程,这些线程与程序的执行线程交替运行...
年轻代GC通常使用ParNew或G1,而老年代则可能采用CMS(Concurrent Mark Sweep)或G1(Garbage-First)。每个算法都有其优势和适用场景,比如,G1 GC旨在提供可预测的停顿时间,适合服务端应用;而CMS则以低延迟为...
通过JVisualVM的Visual GC选项,我们可以观察GC活动,理解其工作模式和效率。 为了详细记录GC日志,可以设置以下JVM参数: - `-verbose:gc`:开启GC信息的输出。 - `-XX:PrintGCDetails`:打印详细的GC信息,包括...
这些数据展示了每次垃圾回收前后堆内存的变化情况,包括新生代垃圾回收(GC)和老年代的完整垃圾回收(FullGC)。格式中的“1860K->1388K(1984K)”表示垃圾回收前年轻代使用了1860KB,回收后减少到1388KB,年轻代总...
- **JVM内部机制**:包括类加载器(Bootstrap、Extension和Application Class-Loader)、内存模型(堆、栈、方法区等)、垃圾收集器(SerialGC、Parallel GC、CMS、G1等)以及JVM调优相关的知识。 - **JDK工具**:如...