GC日志分析

程序代码:

 public class JvmTest {
public static void main(String[] args) { int m = 1024 * 1024;
byte[] b = new byte[2 * m];
System.out.println("allocate 2M"); byte[] b1 = new byte[2 * m];
System.out.println("allocate 2M"); byte[] b2 = new byte[2 * m];
System.out.println("allocate 2M"); byte[] b3 = new byte[2 * m];
System.out.println("allocate 2M"); byte[] b4 = new byte[2 * m];
System.out.println("allocate 2M"); byte[] b5 = new byte[2 * m];
System.out.println("allocate 2M"); byte[] b6 = new byte[2 * m];
System.out.println("allocate 2M");
}
}

一、串行GC

  1、执行命令如下

java -Xms20m -Xmx20m -Xmn10m -XX:+UseSerialGC -XX:+PrintGCDetails JvmTest

  2、GC日志如下:

  

allocate 2M
allocate 2M
allocate 2M
[GC[DefNew: 6831K->231K(9216K), 0.0064660 secs] 6831K->6375K(19456K), 0.0065000 secs] [Times: user=0.01 sys=0.00, real=0.01 secs]
allocate 2M
allocate 2M
allocate 2M
[GC[DefNew: 6547K->6547K(9216K), 0.0000150 secs][Tenured: 6144K->8192K(10240K), 0.0086010 secs] 12691K->12516K(19456K), [Perm : 2585K->2585K(21248K)], 0.0086580 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
allocate 2M
Heap
def new generation total 9216K, used 6509K [0x00000007f9a00000, 0x00000007fa400000, 0x00000007fa400000)
eden space 8192K, 79% used [0x00000007f9a00000, 0x00000007fa05b770, 0x00000007fa200000)
from space 1024K, 0% used [0x00000007fa300000, 0x00000007fa300000, 0x00000007fa400000)
to space 1024K, 0% used [0x00000007fa200000, 0x00000007fa200000, 0x00000007fa300000)
tenured generation total 10240K, used 8192K [0x00000007fa400000, 0x00000007fae00000, 0x00000007fae00000)
the space 10240K, 80% used [0x00000007fa400000, 0x00000007fac000c8, 0x00000007fac00200, 0x00000007fae00000)
compacting perm gen total 21248K, used 2592K [0x00000007fae00000, 0x00000007fc2c0000, 0x0000000800000000)
the space 21248K, 12% used [0x00000007fae00000, 0x00000007fb088230, 0x00000007fb088400, 0x00000007fc2c0000)
No shared spaces configured.

  如上显示首先分配了6M内存后,进行了一次YGC;然后再分配6M内存后进行了一次整个堆的GC。

  上面蓝色字体展示的是第一次YGC的日志,其中 6831K->231K(9216K)  表示年青代的区域大小由6831K较少到231K,即回收了6831-231 = 6600K,9216K表示了年青代占用区域的大小(因为启动参数设置为-Xmn10m,即年青代大小为10M,默认eden和survivor的比例为8:1,所以eden区域为8M,每个survivor区域为1M)。整个堆的大小由6831K减少到6375K,即回收了6831-6375 = 456K。19456K代表了整个年老代、Eden区和一个survivor区域。本次回收共计使用了0.0065000秒。最后一段中user表示YGC用户耗时,sys表示系统耗时,real表示实际耗时。

  下面暗红色的字体展示了整个堆GC,一次YGC和一次PermGC。YGC日志同上。此处Tenured内存没有减少,是因为年青代GC后再分配2M内存,此时年青代中的eden区域为6547K,而eden总大小为8*1024=8192K,如果再分配2M,即6547K+2048K=8595K > 8192K,因此不能在年青代分配内存,只能在年老代分配内存,因此年老大由6144K+2048K=8192K。此时Perm也进行了一次GC,但是没有内存减少。

二、并行GC

A:UseparallelGC

  1、执行命令如下:

java -Xms20m -Xmx20m -Xmn10m -XX:+UseParallelGC -XX:+PrintGCDetails JvmTest

  2、GC日志如下

allocate 2M
allocate 2M
allocate 2M
[GC [PSYoungGen: 6831K->352K(9216K)] 6831K->6496K(19456K), 0.0072050 secs] [Times: user=0.02 sys=0.00, real=0.01 secs]
[Full GC [PSYoungGen: 352K->0K(9216K)] [ParOldGen: 6144K->6373K(10240K)] 6496K->6373K(19456K) [PSPermGen: 2585K->2584K(21504K)], 0.0129170 secs] [Times: user=0.01 sys=0.00, real=0.01 secs]
allocate 2M
allocate 2M
allocate 2M
[Full GC [PSYoungGen: 6315K->4096K(9216K)] [ParOldGen: 6373K->8420K(10240K)] 12689K->12516K(19456K) [PSPermGen: 2584K->2584K(21504K)], 0.0101690 secs] [Times: user=0.01 sys=0.01, real=0.01 secs]
allocate 2M
Heap
PSYoungGen total 9216K, used 6281K [0x00000007ff600000, 0x0000000800000000, 0x0000000800000000)
eden space 8192K, 76% used [0x00000007ff600000,0x00000007ffc22660,0x00000007ffe00000)
from space 1024K, 0% used [0x00000007ffe00000,0x00000007ffe00000,0x00000007fff00000)
to space 1024K, 0% used [0x00000007fff00000,0x00000007fff00000,0x0000000800000000)
ParOldGen total 10240K, used 8420K [0x00000007fec00000, 0x00000007ff600000, 0x00000007ff600000)
object space 10240K, 82% used [0x00000007fec00000,0x00000007ff4391d8,0x00000007ff600000)
PSPermGen total 21504K, used 2591K [0x00000007f9a00000, 0x00000007faf00000, 0x00000007fec00000)
object space 21504K, 12% used [0x00000007f9a00000,0x00000007f9c87e60,0x00000007faf00000)

  如上GC日志所示,JVM进行了3次GC,一次YGC和两次FGC。YGC的日志分析同SerialGC。

  第一次FGC,年青代的大小由352K减少到了0K,因此回收了352K。而年老代由6144K变为6373K,增加了229K(是否为从年青代晋升的对象呢?)。整个堆的大小从6496K减少到6373K,共计回收了6494K-6373K=121K。 Perm区域大小由2585K减少到2584K,共计回收了1K。

  第二次FGC,年青代的大小由6315K减少到4096K,回收了6315K-4096K=2219K。年老代由6373K增加到8420K,增加了2047K,整个堆的大小由12689K减少到12516K,共计回收了12689K-12516K=173K。Perm区域的大小无变化。

B、UseParallelOldGC

  日志同parallelGC。

  UseParallelGC和UseParallelOldGC唯一的不同为:

     -XX:+UseParallelGC用在年青代多线程,年老代单线程,-XX:+UseParallelOldGC用在年青代和年老代都是多线程。

三、CMS GC

  1、命令如下:

    

java -Xms20m -Xmx20m -Xmn10m -XX:+UseConcMarkSweepGC -XX:+PrintGCDetails JvmTest

  2、日志如下: 

[GC[ParNew: 6831K->257K(9216K), 0.0078490 secs] 6831K->6403K(19456K), 0.0079190 secs] [Times: user=0.01 sys=0.01, real=0.01 secs]
[GC[ParNew: 6573K->6573K(9216K), 0.0000550 secs][CMS: 6146K->8192K(10240K), 0.0139330 secs] 12719K->12517K(19456K), [CMS Perm : 2588K->2587K(21248K)], 0.0140560 secs] [Times: user=0.01 sys=0.00, real=0.01 secs]
[GC [1 CMS-initial-mark: 8192K(10240K)] 14565K(19456K), 0.0004510 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[CMS-concurrent-mark: 0.003/0.003 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
[CMS-concurrent-preclean: 0.004/0.004 secs] [Times: user=0.01 sys=0.00, real=0.00 secs]
[CMS-concurrent-abortable-preclean: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[GC[YG occupancy: 7510 K (9216 K)][Rescan (parallel) , 0.0004280 secs][weak refs processing, 0.0000140 secs][scrub string table, 0.0001790 secs] [1 CMS-remark: 9216K(10240K)] 16726K(19456K), 0.0006900 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[CMS-concurrent-sweep: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[CMS-concurrent-reset: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[GC[ParNew: 7510K->7510K(9216K), 0.0000300 secs][CMS: 9216K->9216K(10240K), 0.0088070 secs] 16726K->16615K(19456K), [CMS Perm : 2619K->2619K(21248K)], 0.0089500 secs] [Times: user=0.01 sys=0.00, real=0.00 secs]
[Full GC[CMS: 9216K->9216K(10240K), 0.0062390 secs] 16615K->16603K(19456K), [CMS Perm : 2619K->2619K(21248K)], 0.0062830 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]

  CMS GC的日志多了CMS各个阶段的标识,日志的内容和串行及并行无大区别。

  

也学习Java/JVM/GC(四)的更多相关文章

  1. 系统学习 Java IO (十四)----字符读写缓存和回退 BufferedReader/BufferedWriter & PushbackReader

    目录:系统学习 Java IO---- 目录,概览 BufferedReader BufferedReader 类构造器接收一个 Reader 对象,为 Reader 实例提供缓冲. 缓冲可以加快 I ...

  2. 学习Java的第四天

    一.今日收获 1.java完全手册的第一章 2.   1.6节了解了怎么样用记事本开发java程序 与用Eclipse开发 2.完成了对应例题 二.今日难题 1.一些用法容易与c++的混淆 2.语句还 ...

  3. 学习java随笔第四篇:运算符

    算术运算符 "+":加法运算符,也可做字符连接用途 "-":减法运算符 "*":乘法运算符 "/":除法运算符 &quo ...

  4. 系统学习 Java IO ---- 目录,概览

    Java IO 类的系统教程,原创.主要参考自英文教程 Java IO Tutorial 和 Java Doc. http://tutorials.jenkov.com/java-io/index.h ...

  5. JVM学习(4)——全面总结Java的GC算法和回收机制

    俗话说,自己写的代码,6个月后也是别人的代码……复习!复习!复习!涉及到的知识点总结如下: 一些JVM的跟踪参数的设置 Java堆的分配参数 -Xmx 和 –Xms 应该保持一个什么关系,可以让系统的 ...

  6. JVM学习(4)——全面总结Java的GC算法和回收机制---转载自http://www.cnblogs.com/kubixuesheng/p/5208647.html

    俗话说,自己写的代码,6个月后也是别人的代码……复习!复习!复习!涉及到的知识点总结如下: 一些JVM的跟踪参数的设置 Java堆的分配参数 -Xmx 和 –Xms 应该保持一个什么关系,可以让系统的 ...

  7. Java 中级 学习笔记 2 JVM GC 垃圾回收与算法

    前言 在上一节的学习中,已经了解到了关于JVM 内存相关的内容,比如JVM 内存的划分,以及JDK8当中对于元空间的定义,最后就是字符串常量池等基本概念以及容易混淆的内容,我们都已经做过一次总结了.不 ...

  8. java jvm学习笔记十三(jvm基本结构)

    欢迎装载请说明出处:http://blog.csdn.net/yfqnihao 这一节,主要来学习jvm的基本结构,也就是概述.说是概述,内容很多,而且概念量也很大,不过关于概念方面,你不用担心,我完 ...

  9. java jvm内存管理/gc策略/参数设置

    1. JVM内存管理:深入垃圾收集器与内存分配策略 http://www.iteye.com/topic/802638 Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外面的人想 ...

随机推荐

  1. 401 Not Authorized For MSDEPLOY‏ (msdeployAgentService)

    When you get this error from msdeploy:“Error: The remote server returned an error: (401) Unauthorize ...

  2. 编码UTF-8

    ☯,首先,这并不是图片,这是一个unicode字符,Yin Yang,即阴阳符,码点为U+262F.如果你的浏览器无法显示,可以查看这个链接http://www.fileformat.info/inf ...

  3. HDMI学习

    市面上大多4K显示器都配备了HDMI 1.4接口,仅能实现30Hz的刷新率,不足以带来流畅的显示效果, 酱紫情况,就算是搭配了HDMI 2.0高清线也是无法发挥其作用.只有更先进的HDMI 2.0标准 ...

  4. WebConfig 自定义节点configSections配置信息

    WebConfig 自定义节点configSections配置信息 示例: <configuration>   <configSections>     <!-- For ...

  5. 浅谈Oracle表之间各种连接

    Oracle表之间的连接分为三种: 1.内连接(自然连接) 2.外连接 2.1.左外连接(左边的表不加限制,查询出全部满足条件的结果) 2.2.右外连接(右边的表不加限制,查询出全部满足条件的结果) ...

  6. Linux 流程控制语句 if else、for、while、until

    1. 单分支if条件语句 书写方式1: if [ 条件判断式 ]; then 执行程序代码 fi 书写方式2: if [ 条件判断式 ] then 执行程序代码 fi 举例: if [ $rate - ...

  7. Win7(32bit)下Qt5.5.0和OpenCV2.4.9环境的搭建

    之前一直基于Windows平台(Win 7 32bit)使用VS2010做OpenCV的开发,现在开始学习在Windows 下使用Qt做OpenCV的开发.本文主要讲述Windows平台下(Win 7 ...

  8. survey on Time Series Analysis Lib

    (1)I spent my 4th year Computing project on implementing time series forecasting for Java heap usage ...

  9. Linux下GDB调试

    GDB 是一个强大的命令行调试工具.大家知道命令行的强大就是在于,其可以形成执行 序列,形成脚本.UNIX 下的软件全是命令行的,这给程序开发提供了极大的便利,命令行 软件的优势在于, 他们可以非常容 ...

  10. Ajax Step By Step5

    第五.[表单序列化] Ajax 用的最多的地方莫过于表单操作,而传统的表单操作是通过 submit 提交将数据传 输到服务器端.如果使用 Ajax 异步处理的话,我们需要将每个表单元素逐个获取才方能提 ...