查看GC日志

查看GC日志

java -verbose:gc -Xms20M -Xmx30M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8 -Xloggc:D:\tmp\java\gc1.log

Java HotSpot(TM) 64-Bit Server VM (25.45-b02) for windows-amd64 JRE (1.8.0_45-b15), built on Apr 30 2015 12:40:44 by "java_re" with MS VC++ 10.0 (VS2010)
Memory: 4k page, physical 33440828k(24503856k free), swap 38421564k(22318252k free)
CommandLine flags: -XX:InitialHeapSize=20971520 -XX:MaxHeapSize=31457280 -XX:MaxNewSize=10485760 -XX:NewSize=10485760 -XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:SurvivorRatio=8 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC 
Heap
 PSYoungGen      total 9216K, used 1967K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)
  eden space 8192K, 24% used [0x00000000ff600000,0x00000000ff7ebf98,0x00000000ffe00000)
  from space 1024K, 0% used [0x00000000fff00000,0x00000000fff00000,0x0000000100000000)
  to   space 1024K, 0% used [0x00000000ffe00000,0x00000000ffe00000,0x00000000fff00000)
 ParOldGen       total 10240K, used 0K [0x00000000fe200000, 0x00000000fec00000, 0x00000000ff600000)
  object space 10240K, 0% used [0x00000000fe200000,0x00000000fe200000,0x00000000fec00000)
 Metaspace       used 3459K, capacity 4554K, committed 4864K, reserved 1056768K
  class space    used 377K, capacity 386K, committed 512K, reserved 1048576K

在eclipse中设置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   日志文件的输出路径

程序

public class TestGcLog {	
	 public static void main(String[] args) {
		 int _1m = 1024 * 1024;
	     byte[] data = new byte[_1m];
	  // 将data置为null即让它成为垃圾
        data = null;
        // 通知垃圾回收器回收垃圾
        System.gc();
	}
}

输出GC日志:

[GC (System.gc()) [PSYoungGen: 5263K->712K(153088K)] 5263K->720K(502784K), 0.0014977 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC (System.gc()) [PSYoungGen: 712K->0K(153088K)] [ParOldGen: 8K->531K(349696K)] 720K->531K(502784K), [Metaspace: 2549K->2549K(1056768K)], 0.0052235 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 
Heap
 PSYoungGen      total 153088K, used 1316K [0x0000000715e00000, 0x0000000720880000, 0x00000007c0000000)
  eden space 131584K, 1% used [0x0000000715e00000,0x0000000715f490d0,0x000000071de80000)
  from space 21504K, 0% used [0x000000071de80000,0x000000071de80000,0x000000071f380000)
  to   space 21504K, 0% used [0x000000071f380000,0x000000071f380000,0x0000000720880000)
 ParOldGen       total 349696K, used 531K [0x00000005c1a00000, 0x00000005d6f80000, 0x0000000715e00000)
  object space 349696K, 0% used [0x00000005c1a00000,0x00000005c1a84e50,0x00000005d6f80000)
 Metaspace       used 2555K, capacity 4486K, committed 4864K, reserved 1056768K
  class space    used 273K, capacity 386K, committed 512K, reserved 1048576K
  • GC日志开头的”[GC”和”[Full GC”说明了这次垃圾收集的停顿类型,如果有”Full”,说明这次GC发生了”Stop-The-World”。因为是调用了System.gc()方法触发的收集,所以会显示”[Full GC (System.gc())”,不然是没有后面的(System.gc())的。
  • “[PSYoungGen”和”[ParOldGen”是指GC发生的区域,分别代表使用Parallel Scavenge垃圾收集器的新生代和使用Parallel old垃圾收集器的老生代。为什么是这两个垃圾收集器组合呢?因为我的jvm开启的模式是Server,而Server模式的默认垃圾收集器组合便是这个,在命令行输入java -version就可以看到自己的jvm默认开启模式。还有一种是client模式,默认组合是Serial收集器和Serial Old收集器组合。
  • 在方括号中”PSYoungGen:”后面的”5263K->712K(153088K)”代表的是”GC前该内存区域已使用的容量->GC后该内存区域已使用的容量(该内存区域总容量)”
  • 在方括号之外的”5263K->720K(502784K)”代表的是”GC前Java堆已使用容量->GC后Java堆已使用容量(Java堆总容量)”
  • 0.0014977 secs 代表该内存区域GC所占用的时间,单位是秒。
  • [Times: user=0.00 sys=0.00, real=0.00 secs] user代表进程在用户态消耗的CPU时间,sys代表代表进程在内核态消耗的CPU时间、real代表程序从开始到结束所用的时钟时间。这个时间包括其他进程使用的时间片和进程阻塞的时间(比如等待 I/O 完成)。
  • PSYoungGen total 153088K, used 1316K 表示新生代
  • eden space 131584K, 1% used eden区
  • from space 21504K, 0% used to space 21504K, 0% used s0或s1区
  • ParOldGen total 349696K, used 531K 老年代

配置对应关系图

  • 新生代GC(Minor GC):指发生在新生代的垃圾收集动作,因为Java对象大多都具备朝生夕灭的特性,所以Minor GC非常频繁,一般回收速度非常快。
  • 老年代GC(Major GC/Full GC):指发生在老年代的GC,出现了Major GC,经常会伴随至少一次的Minor GC,Major GC的速度一般会比Minor GC慢10倍以上。

[Full GC (System.gc()) [PSYoungGen: 712K->0K(153088K)] [ParOldGen: 8K->531K(349696K)] 720K->531K(502784K), [Metaspace: 2549K->2549K(1056768K)], 0.0052235 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]

说明 从左到右分别为

[GC类型 (System.gc()) [Young区: GC前Young的内存占用->GC后Young的内存占用(Young区域总大小)] [old老年代: GC前Old的内存占用->GC后Old的内存占用(Old区域总大小)] GC前堆内存占用->GC后堆内存占用(JVM堆总大小), [永久代区: GC前占用大小->C后占用大小(永久代区总大小)], GC用户耗时] [Times:用户耗时 sys=系统时间, real=实际时间]

规律

[名称:gc前内存占用-> gc后内存占用(该区内存总大小)]

jstat 命令查看

命令格式: jstat - [-t] [-h] [ []]

通过 jps 查看java 进程ID

再通过

jstat -gc -h3 11940 2500 12**

如下表示分析进程id为11940 的gc情况,每隔2500ms打印一次记录,打印12次停止,每3行后打印指标头部

C:\Users\user>jstat -gc -h3 11940  2500 12
 S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT
18944.0 34816.0  0.0    0.0   365056.0 329793.6  524288.0   61827.2   75776.0 70086.5 10240.0 9249.4     16    0.202   4      0.961    1.163
18944.0 34816.0  0.0    0.0   365056.0 329793.6  524288.0   61827.2   75776.0 70086.5 10240.0 9249.4     16    0.202   4      0.961    1.163
18944.0 34816.0  0.0    0.0   365056.0 329793.6  524288.0   61827.2   75776.0 70086.5 10240.0 9249.4     16    0.202   4      0.961    1.163
 S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT
18944.0 34816.0  0.0    0.0   365056.0 329793.6  524288.0   61827.2   75776.0 70086.5 10240.0 9249.4     16    0.202   4      0.961    1.163
18944.0 34816.0  0.0    0.0   365056.0 330762.1  524288.0   61827.2   75776.0 70086.5 10240.0 9249.4     16    0.202   4      0.961    1.163
18944.0 34816.0  0.0    0.0   365056.0 330762.1  524288.0   61827.2   75776.0 70086.5 10240.0 9249.4     16    0.202   4      0.961    1.163
 S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT
18944.0 34816.0  0.0    0.0   365056.0 330762.1  524288.0   61827.2   75776.0 70086.5 10240.0 9249.4     16    0.202   4      0.961    1.163
18944.0 34816.0  0.0    0.0   365056.0 330762.1  524288.0   61827.2   75776.0 70086.5 10240.0 9249.4     16    0.202   4      0.961    1.163
18944.0 34816.0  0.0    0.0   365056.0 330762.1  524288.0   61827.2   75776.0 70086.5 10240.0 9249.4     16    0.202   4      0.961    1.163
 S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT
18944.0 34816.0  0.0    0.0   365056.0 330762.1  524288.0   61827.2   75776.0 70086.5 10240.0 9249.4     16    0.202   4      0.961    1.163
18944.0 34816.0  0.0    0.0   365056.0 330762.1  524288.0   61827.2   75776.0 70086.5 10240.0 9249.4     16    0.202   4      0.961    1.163
18944.0 34816.0  0.0    0.0   365056.0 330762.1  524288.0   61827.2   75776.0 70086.5 10240.0 9249.4     16    0.202   4      0.961    1.163
参数 描述

S0C 年轻代中第一个survivor(幸存区)的容量 (字节)
S1C 年轻代中第二个survivor(幸存区)的容量 (字节)
S0U 年轻代中第一个survivor(幸存区)目前已使用空间 (字节)
S1U 年轻代中第二个survivor(幸存区)目前已使用空间 (字节)
EC 年轻代中Eden(伊甸园)的容量 (字节)
EU 年轻代中Eden(伊甸园)目前已使用空间 (字节)
OC Old代的容量 (字节)
OU Old代目前已使用空间 (字节)
PC Perm(持久代)的容量 (字节)
PU Perm(持久代)目前已使用空间 (字节)
YGC 从应用程序启动到采样时年轻代中gc次数
YGCT 从应用程序启动到采样时年轻代中gc所用时间(s)
FGC 从应用程序启动到采样时old代(全gc)gc次数
FGCT 从应用程序启动到采样时old代(全gc)gc所用时间(s)

GCT 从应用程序启动到采样时gc用的总时间(s)

jstat -gcutil
C:\Users\user>jstat -gcutil 11940
  S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT
  0.00   0.00  93.06  11.79  92.49  90.33     16    0.202     4    0.961    1.163
参数 描述

S0 年轻代中第一个survivor(幸存区)已使用的占当前容量百分比
S1 年轻代中第二个survivor(幸存区)已使用的占当前容量百分比
E 年轻代中Eden(伊甸园)已使用的占当前容量百分比
O old代已使用的占当前容量百分比
P perm代已使用的占当前容量百分比
YGC 从应用程序启动到采样时年轻代中gc次数
YGCT 从应用程序启动到采样时年轻代中gc所用时间(s)
FGC 从应用程序启动到采样时old代(全gc)gc次数
FGCT 从应用程序启动到采样时old代(全gc)gc所用时间(s)
GCT 从应用程序启动到采样时gc用的总时间(s)

jstat -gccapacity

C:\Users\user>jstat -gccapacity 11940
 NGCMN    NGCMX     NGC     S0C   S1C       EC      OGCMN      OGCMX       OGC         OC       MCMN     MCMX      MC     CCSMN    CCSMX     CCSC    YGC    FGC
174592.0 2787328.0 466432.0 18944.0 34816.0 365056.0   349696.0  5574656.0   524288.0   524288.0      0.0 1114112.0  75776.0      0.0 1048576.0  10240.0     16     4
参数 描述

NGCMN 年轻代(young)中初始化(最小)的大小 (字节)
NGCMX 年轻代(young)的最大容量 (字节)
NGC 年轻代(young)中当前的容量 (字节)
S0C 年轻代中第一个survivor(幸存区)的容量 (字节)
S1C 年轻代中第二个survivor(幸存区)的容量 (字节)
EC 年轻代中Eden(伊甸园)的容量 (字节)
OGCMN old代中初始化(最小)的大小 (字节)
OGCMX old代的最大容量 (字节)
OGC old代当前新生成的容量 (字节)
OC Old代的容量 (字节)
PGCMN perm代中初始化(最小)的大小 (字节)
PGCMX perm代的最大容量 (字节)
PGC perm代当前新生成的容量 (字节)
PC Perm(持久代)的容量 (字节)
YGC 从应用程序启动到采样时年轻代中gc次数
FGC 从应用程序启动到采样时old代(全gc)gc次数

其他命令
  1. 查看年轻代对象的信息及其占用量。

jstat -gcnewcapacity xxxx
1
2) 查看老年代对象的信息及其占用量。

jstat -gcoldcapacity xxxx
1
3) 查看年轻代对象的信息

jstat -gcnew xxxx
1
4) 查看老年代对象的信息

jstat -gcold xxxx

查看GC日志的目的就是为了调优jvm

新生代日志
[GC (System.gc()) [PSYoungGen: 5263K->712K(153088K)] 5263K->720K(502784K), 0.0014977 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
Full gc 日志
[Full GC (System.gc()) [PSYoungGen: 712K->0K(153088K)] [ParOldGen: 8K->531K(349696K)] 720K->531K(502784K), [Metaspace: 2549K->2549K(1056768K)], 0.0052235 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
JVM调优工具
  • jps命令:查看JVM启动的所有进程、执行主类的全名、JVM启动参数
  • jstat命令:监视虚拟机信息,例jstat -gc pid 500 10(每500ms打印各个区容量、使用容量、gc时间,打印10次)
  • jmap命令:查看堆内存信息,例jmap -histo pid(打印当前堆中每个类的实例数量和内存占用)
  • jhat命令:通过浏览器分析对应的内存快照,例jhat -port 9810 -J-Xmx4G /data/jvm/dumpfile_jmap.hprof(以9810端口启动jhat内嵌的服务器)
  • jconsole / jvisualvm:分析内存信息(各个区内存变化情况)

说明:

一般情况采用默认配置,在测试中根据系统运行状况和GC日志、内存监控进行合理调整
新生代越大,老年代越小,Full GC 频率越高,但 Full GC 时间短
新生代越小,老年代越大,Full GC 频率越低,但 Full GC 时间长

参数设置:

-Xms和-Xmx的值设成相等,Heap不够用时,会发生内存抖动,影响程序运行稳定性
堆大小默认为-Xms指定大小;
默认空闲堆内存小于40%时,JVM会扩大堆到-Xmx指定的大小;
空闲堆内存大于70%时,JVM会减小堆到Xms指定大小;
如果在 Full GC 后满足不了内存需求会动态调整,这个阶段比较耗费资源

新生代尽量设置大一些,让对象在新生代多存活一段时间,每次 Minor GC 都要尽可能多的收集垃圾对象,防止或延迟对象进入老年代的机会,从而减少 Full GC 的频率

老年代如果使用CMS收集器,新生代可以不用太大(CMS并行收集速度很快,可以和用户线程并发执行)

方法区大小设置,1.6之前需要考虑系统运行时动态增加的常量、静态变量,1.7只要能装下类信息就可以

代码实现:

避免创建过大的对象及数组:过大对象在新生代没有足够空间会直接进入老年代,如果是短命大对象,会提前触发 Full GC
避免同时加载大量数据:可以分批读取,用完后尽快清空引用
用完尽快清空集合中对象的引用: 尽快回收,避免进入老年代
在合适场景采用软引用、弱引用:内存溢出前会把它们列入回收范围进行二次回收
避免产生死循环:死循环产生后,可能产生大量实例,导致空间占满

JVM参数

参考:

https://blog.csdn.net/huyuyang6688/article/details/81490570

其他堆空间的分配,基于以下规则来进行

基于以上规则和上图中的FullGC信息,我们现在可以规划的该应用堆空间为:

[Full GC (System.gc()) 
[PSYoungGen: 712K->0K(153088K)]
[ParOldGen: 8K->531K(349696K)] 720K->531K(502784K), 
[Metaspace: 2549K->2549K(1056768K)], 0.0052235 secs] 
[Times: user=0.00 sys=0.00, real=0.01 secs] 

java 堆空间: 2000Mb (=老年代空间502784kb*4)

新生代空间:750Mb(=老年代空间502784kb*1.5)

永久代空间:25Mb(=永久代空间2549kb*1.5)

老年代空间: 1250Mb=堆空间-新生代看空间=2000MbMb-750Mb

对应的应用启动参数应该为:

java -Xms373m -Xmx373m -Xmn140m -XX:PermSize=5m -XX:MaxPermSize=5m

查看字节码明细

javap -verbose xxx.class 非常明细

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值