分析 java gc日志_JVM-GC日志查看分析

1.怎么查看日志

首先在eclipse中准备一个Gcdemo.java

package leetcode;

public class Gcdemo {

public static void main(String[] args) {

int _1m = 1024 * 1024;

byte[] data = new byte[_1m];

// 将data置为null即让它成为垃圾

data = null;

// 通知垃圾回收器回收垃圾

System.gc();

}

}

按如下图运行这个demo 右键- Run AS - Run Configurations

0ed902739aa0

输入如下图参数-XX:+PrintGCDetails

0ed902739aa0

得到如图内容

0ed902739aa0

当然也可以通过cmd的形式。

在工程的bin层打开cmd 输入命令:java -XX:+PrintGCDetails leetcode.Gcdemo

0ed902739aa0

2.GC日志的参数

首先了解关于输出GC日志的参数有以下几种

-XX:+PrintGC 输出GC日志

-XX:+PrintGCDetails 输出GC的详细日志

-XX:+PrintGCTimeStamps 输出GC的时间戳(以基准时间的形式)

-XX:+PrintGCDateStamps 输出GC的时间戳(以日期的形式,如 2013-05-04T21:53:59.234+0800)

-XX:+PrintHeapAtGC 在进行GC的前后打印出堆的信息

-Xloggc:../logs/gc.log 日志文件的输出路径

3.分析日志

[GC (System.gc()) [PSYoungGen: 2908K->680K(54784K)] 2908K->688K(180736K), 0.0314018 secs] [Times: user=0.00 sys=0.00, real=0.07 secs]

[Full GC (System.gc()) [PSYoungGen: 680K->0K(54784K)] [ParOldGen: 8K->530K(125952K)] 688K->530K(180736K), [Metaspace: 2656K->2656K(1056768K)], 0.0115257 secs] [Times: user=0.03 sys=0.00, real=0.01 secs]

Heap

PSYoungGen total 54784K, used 471K [0x0000000782f00000, 0x0000000786c00000, 0x00000007c0000000)

eden space 47104K, 1% used [0x0000000782f00000,0x0000000782f75da0,0x0000000785d00000)

from space 7680K, 0% used [0x0000000785d00000,0x0000000785d00000,0x0000000786480000)

to space 7680K, 0% used [0x0000000786480000,0x0000000786480000,0x0000000786c00000)

ParOldGen total 125952K, used 530K [0x0000000708c00000, 0x0000000710700000, 0x0000000782f00000)

object space 125952K, 0% used [0x0000000708c00000,0x0000000708c84848,0x0000000710700000)

Metaspace used 2663K, capacity 4486K, committed 4864K, reserved 1056768K

class space used 288K, capacity 386K, committed 512K, reserved 1048576K

①GC日志开头的[GC和[Full GC说明了这次垃圾收集的类型.

Partial GC(局部 GC): 并不收集整个 GC 堆的模式

- Young GC: 只收集young gen的GC,Young GC还有种说法就叫做 "Minor GC"

- Old GC: 只收集old gen的GC。只有垃圾收集器CMS的concurrent collection 是这个模式

- Mixed GC: 收集整个young gen 以及部分old gen的GC。只有垃圾收集器 G1有这个模式

Full GC 就是收集整个堆,包括新生代,老年代,永久代(在JDK 1.8及以后,永久代会被移除,换为metaspace(元空间))等收集所有部分的模式。

针对不同的垃圾收集器,Full GC的触发条件可能不都一样。按HotSpot VM的serial GC的实现来看,触发条件是:

1.当准备要触发一次 young GC时,如果发现统计数据说之前 young GC的平均晋升大小比目前的 old gen剩余的空间大,则不会触发young GC而是转为触发 full GC

(因为HotSpot VM的GC里,除了垃圾回收器 CMS的concurrent collection 之外,其他能收集old gen的GC都会同时收集整个GC堆,包括young gen,所以不需要事先准备一次单独的young GC)

2.如果有永久代(perm gen),要在永久代分配空间但已经没有足够空间时,也要触发一次 full GC

3.执行System.gc(),heap dump带GC,其默认都是触发 full GC.

②[PSYoungGen和[ParOldGen是指GC发生的区域,分别代表使用Parallel Scavenge垃圾收集器的新生代和使用Parallel old垃圾收集器的老生代。为什么是这两个垃圾收集器组合呢?因为我的jvm开启的模式是Server,而Server模式的默认垃圾收集器组合便是这个,在命令行输入java -version就可以看到自己的jvm默认开启模式。还有一种是client模式,默认组合是Serial收集器和Serial Old收集器组合。

0ed902739aa0

③在方括号中PSYoungGen:后面的2908K->680K(54784K)代表的是GC前该内存区域已使用的容量->GC后该内存区域已使用的容量(该内存区域总容量)

④在方括号之外的2908K->688K(180736K)代表的是GC前Java堆已使用容量->GC后Java堆已使用容量(Java堆总容量)

⑤再往后的0.0314018 secs代表该内存区域GC所占用的时间,单位是秒。

⑥再后面的[Times: user=0.00 sys=0.00, real=0.07 secs],user代表进程在用户态消耗的CPU时间,sys代表代表进程在内核态消耗的CPU时间、real代表程序从开始到结束所用的时钟时间。这个时间包括其他进程使用的时间片和进程阻塞的时间(比如等待 I/O 完成)

下面是堆详细信息的日志

Heap

PSYoungGen total 54784K, used 471K [0x0000000782f00000, 0x0000000786c00000, 0x00000007c0000000)

eden space 47104K, 1% used [0x0000000782f00000,0x0000000782f75da0,0x0000000785d00000)

from space 7680K, 0% used [0x0000000785d00000,0x0000000785d00000,0x0000000786480000)

to space 7680K, 0% used [0x0000000786480000,0x0000000786480000,0x0000000786c00000)

ParOldGen total 125952K, used 530K [0x0000000708c00000, 0x0000000710700000, 0x0000000782f00000)

object space 125952K, 0% used [0x0000000708c00000,0x0000000708c84848,0x0000000710700000)

Metaspace used 2663K, capacity 4486K, committed 4864K, reserved 1056768K

class space used 288K, capacity 386K, committed 512K, reserved 1048576K

先了解下Java memory划分:

Java memory主要分heap memory和non-heap memory,如下图:

0ed902739aa0

⑦第一行为新生代的大小,大小为54784K。而新生代又分为三个区域分别叫Eden,和俩个Survivor spaces(from和to)。Eden用来存放新的对象,Survivor spaces用于 新对象 升级到Tenured area时的 拷贝。默认的,Edem : from : to = 8 : 1 : 1( 可以通过参数–XX:SurvivorRatio来设定 ),即:Eden = 8/10 的新生代空间大小,from = to = 1/10的新生代空间大小。

⑧默认的,新生代 ( Young) 与老年代 ( Old ) 的比例的值为 1:2( 该值可以通过参数–XX:NewRatio来指定 ),即:新生代 ( Young) = 1/3的堆空间大小。老年代 ( Old) = 2/3 的堆空间大小。其中,新生代 ( Young) 被细分为 Eden 和 两个 Survivor区域,这两个 Survivor区域分别被命名为 from 和 to,以示区分。

⑨ParOldGen为老年代,大小为125952K,大约为PSYoungGen内存大小的2倍。 从JDK8开始,永久代(PermGen)的概念被废弃掉了,取而代之的是一个称为Metaspace(元空间)的存储空间。Metaspace与PermGen之间最大的区别在于:Metaspace并不在虚拟机中,而是使用本地内存。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值