GC日志分析

阅读GC日志是处理Java虚拟机内存问题的基础技能,它是一些人为确定的规则,没什么太多技术含量. GC日志可以使用很多工具看到.下面是将日志输出到本地磁盘的文件夹中.

1.首先了解一下基础的JVM参数

-Xms:初始堆大小,默认为物理内存的1/64(<1GB);默认(MinHeapFreeRatio参数可以调整)空余堆内存小于40%时,JVM就会增大堆直到-Xmx 的最大限制
-Xmx:堆的最大空间大小。默认(MaxHeapFreeRatio参数可以调整)空余堆内存大于70%时,JVM会减少堆直到 -Xms的最小限制
-XX:NewSize 新生代最小空间大小。
-XX:MaxNewSize 新生代最大空间大小。
-XX:PermSize 设置永久代(perm gen)初始值。默认值为物理内存的1/64
-XX:MaxPermSize 设置持久代最大值。物理内存的1/4-Xss:每个线程的堆栈大小, JDK5.0以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K。应根据应用的线程所
需内存大小进行适当调整。在相同物理内存下,减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数还是
有限制的,不能无限生成,经验值在3000~5000左右。一般小的应用, 如果栈不是很深, 应该是128k够用的,大的应
用建议使用256k。这个选项对性能影响比较大,需要严格的测试。和threadstacksize选项解释很类似,官方文档似乎
没有解释,在论坛中有这样一句话:”-Xss is translated in a VM flag named ThreadStackSize”一般设置这
个值就可以了。
-Xmn:新生代的内存空间大小,注意:此处的大小是(eden+ 2 survivor space)。与jmap -heap中显示的New
gen是不同的。整个堆大小=新生代大小 + 老生代大小 + 永久代大小。 在保证堆大小不变的情况下,增大新生代后,
将会减小老生代大小。此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8-XX:SurvivorRatio:新生代中Eden区域与Survivor区域的容量比值,默认值为8。两个Survivor区与一个Eden区的比值为2:8,一个Survivor区占整个年轻代的1/10。

2.D盘创建一个 GClogs文件夹,启动idea,随便写个小demo

使用一下<<深入理解JVM>>书中的例子

public class TestGcDemo {

    private static final int _1MB = 1024 * 1024;  //定义常量1MB大小

    /*
    * vm参数:  -verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails
    *  -XX:+PrintGCTimeStamps -XX:+PrintGCDetails -Xloggc:d:/GClogs/tomcat8-gc.log
    * */
    public static void main(String[] args) {

        byte[] allocation1, allocation2, allocation3, allocation4;
        allocation1 = new byte[2 * _1MB];
        allocation2 = new byte[2 * _1MB];
        allocation3 = new byte[2 * _1MB];
        allocation4 = new byte[4 * _1MB];  //出现一次minorGc


        System.out.println("-----------end------------");

    }
}

 

Window下idea的VM参数设置如下,tomcat7-gc.log表示输出日志到这个文件里面

-verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCTimeStamps -XX:+PrintGCDetails -Xloggc:d:/GClogs/tomcat7-gc.log

 

然后运行一下代码,找到d:/GClogs/tomcat7-gc.log文件

 

 

 3.选一个分析一下

0.177: [GC (Allocation Failure) [PSYoungGen: 6666K->799K(9216K)] 6666K->4903K(19456K), 0.0119057 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]

 

 0.177 表示GC发生时间,即从Java虚拟机启动以来经过的秒数;

[GC 表示 垃圾收集的停顿类型,若前面有Full则表明是Full GC,没有Full的修饰表明这是一次Minor GC 。注意它不表示只GC新生代;

Allocation Failure 括号里的内容是gc发生的原因,这里的Allocation Failure的原因是年轻代中没有足够区域能够存放需要分配的数据而失败;

PSYoungGen表示GC发生区域

6666K表示 GC前该内存区域已使用容量

799K表示 GC后该内存区域已使用容量

9216K表示 该内存区域总容量

6666K表示 GC前Java堆已使用容量

4903K表示 GC后Java堆已使用容量

19456K表示 GC前Java堆总容量

 0.0119057 secs表示 改内存区域GC占用时间,单位是秒

user/sys/real 表示 分别代表用户态消耗的CPU时间,内核态消耗的CPU时间和操作从开始到结束锁经过的墙钟时间.

 

4.再补一个内存模型

 (上图出处:https://blog.csdn.net/qq_19734597/article/details/80958817)

 

posted @ 2019-11-13 11:36  将军上座  阅读(628)  评论(0编辑  收藏  举报