javajava Parallel GC 该怎么看?
Posted 九师兄
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了javajava Parallel GC 该怎么看?相关的知识,希望对你有一定的参考价值。
1.概述
转载:http://anyteam.me/garbage-collection-algorithms-parallel-gc/
建议看原文。
这个组合的垃圾收集器使用标记-复制的方式清理年轻代,使用标记-清除-整理的方式清理老年代。它们都会触发Stop-the-world暂停,挂起应用的全部线程。它们都会使用多线程来运行标记和复制/整理,这也是Parallel GC名字的由来。使用这种方法,垃圾收集的次数会明显减少很多。
垃圾收集时使用的线程数可以通过参数-XX:ParallelGCThreads=NNN设置,默认值为系统硬件的 CPU 核心数。
要使用Parallel GC,可以选择下面三种方式之一来启动 JVM。
java -XX:+UseParallelGC com.mypackages.MyExecutableClass
java -XX:+UseParallelOldGC com.mypackages.MyExecutableClass
java -XX:+UseParallelGC -XX:+UseParallelOldGC com.mypackages.MyExecutableClass
在多核 CPU 环境下,如果你得首要目的是增加系统吞吐量,那么Parallel GC非常合适。更高的吞吐量是由更高效的资源利用率带来的:
- 垃圾收集时,所有的 CPU 核心并行做垃圾清理,带来了更短的暂停时间;
- 在垃圾收集事件之间,收集器不占用任何资源。
另一方面,因为垃圾收集的所有阶段都不能被打断,Parallel GC还是有可能导致长时间的应用暂停。因此,如果低延时是你的首要目标,那么你应该去看看CMS 垃圾收集算法。
让我们来看看使用Parallel GC时,垃圾收集日志长什么样,我们能从中得到哪些信息。下面的日志包含了 2 次垃圾收集事件:Minor GC和Full GC。
2015-05-26T14:27:40.915-0200: 116.115: [GC (Allocation Failure) [PSYoungGen: 2694440K->1305132K(2796544K)] 9556775K->8438926K(11185152K), 0.2406675 secs] [Times: user=1.77 sys=0.01, real=0.24 secs]
2015-05-26T14:27:41.155-0200: 116.356: [Full GC (Ergonomics) [PSYoungGen: 1305132K->0K(2796544K)] [ParOldGen: 7133794K->6597672K(8388608K)] 8438926K->6597672K(11185152K), [Metaspace: 6745K->6745K(1056768K)], 0.9158801 secs] [Times: user=4.49 sys=0.64, real=0.92 secs]
Minor GC
下面是第一段日志片段,包含了清理年轻代的垃圾收集事件信息:
2015-05-26T14:27:40.915-0200 : 116.115 : [GC (Allocation Failure) [PSYoungGen : 2694440K->1305132K (2796544K) ] 9556775K->8438926K (11185152K), 0.2406675 secs] [Times: user=1.77 sys=0.01, real=0.24 secs]
2015-05-26T14:27:40.915-0200 – GC 开始时间。
116.115 – GC 开始时间,相对于 JVM 的启动时间的偏移,单位秒。
GC – 标志位:Minor GC或Full GC。本次为Minor GC。
Allocation Failure – 触发垃圾收集的原因。本次为年轻代空间不足以分配新对象。
PSYoungGen – 使用的垃圾收集器名称,代表使用的是并行标记-复制且Stop-the-world的垃圾收集器清理年轻代。
2694440K->1305132K – 垃圾收集前后年轻代空间使用量。
(2796544K) – 年轻代空间大小。
9556775K->8438926K – 垃圾收集前后堆上空间使用量。
(11185152K) – 堆大小。
0.2406675 secs – 垃圾收集时长,单位秒。
[Times: user=1.77 sys=0.01, real=0.24 secs] – 分类统计的垃圾收集时长:
user:垃圾收集中的线程占用的 CPU 总时间
sys:系统调用和等待系统事件占用的 CPU 时间
real:应用暂停时长。使用Paralled GC时,real≈(user+sys) / countOfThreadsUsedInGC,本次 GC 中使用了 8 个线程。要注意,GC 中总有一些操作是不能并行执行的,因此,实际的real值一般会比计算出来的值大一些。
总之,垃圾收集之前堆的使用量为 9,556,775K,其中年轻代使用量为 2,694,440K,那么可算出老年代使用量为 6,862,335K。垃圾收集之后,年轻代使用量下降了 1,389,308K,但堆的使用量只下降了 1,117,849K,意味着有 271,459K的对象从年轻代提升到了老年代。
Full GC
了解了上面清理年轻代的垃圾收集日志,下面通过分析第二段日志看看整个堆是怎么被清理的。
2015-05-26T14:27:41.155-0200 : 116.356 : [Full GC (Ergonomics) [PSYoungGen: 1305132K->0K(2796544K)] [ParOldGen : 7133794K->6597672K (8388608K)] 8438926K->6597672K (11185152K), [Metaspace: 6745K->6745K(1056768K)], 0.9158801 secs, [Times: user=4.49 sys=0.64, real=0.92 secs]
2015-05-26T14:27:41.155-0200 – GC 开始时间。
116.356 – GC 开始时间,相对于 JVM 的启动时间的偏移,单位秒。
Full GC – 标志位:Minor GC或Full GC。本次为清理年轻代和老年代的Full GC。
Ergonomics – GC 发生的原因。Ergonomics表明 JVM 觉得是时候做些垃圾清理工作了。
[PSYoungGen: 1305132K->0K(2796544K)] – 跟上面的例子类似,它是一个叫PSYoungGen的并发标记-复制且Stop-the-world的垃圾收集器。年轻代的使用量降到了 0,这也是Full GC的一般结果。
ParOldGen – 清理老年代的垃圾收集器类型。这是一个叫ParOldGen的并行标记-清除-整理且Stop-the-world的垃圾收集器。
7133794K->6597672K – 垃圾收集前后老年代使用量。
(8388608K) – 老年代空间大小。
8438926K->6597672K – 垃圾收集前后堆上空间使用量。
(11185152K) – 堆大小。
[Metaspace: 6745K->6745K(1056768K)] – 垃圾收集前后元数据区使用量。这里没有变化。
0.9158801 secs – 垃圾收集时长,单位秒。
[Times: user=4.49 sys=0.64, real=0.92 secs] – 分类统计的垃圾收集时长:
user:垃圾收集中的线程占用的 CPU 总时间
sys:系统调用和等待系统事件占用的 CPU 时间
real:应用暂停时长。使用Paralled GC时,real≈(user+sys) / countOfThreadsUsedInGC,本次 GC 中使用了 8 个线程。要注意,GC 中总有一些操作是不能并行执行的,因此,实际的real值一般会比计算出来的值大一些。
Full GC跟Minor GC的区别很明显 – 除了年轻代,老年代和元数据区同样被清理了。下图示意了Full GC前后内存使用情况。
以上是关于javajava Parallel GC 该怎么看?的主要内容,如果未能解决你的问题,请参考以下文章
Java默认垃圾回收器Parallel Scavenge导致Full GC增加
JVM 技术详解:常见的 GC 算法(Parallel/CMS/G1)