Java GC就是JVM记录仪,书画了JVM各个分区的表演。html
Java GC(Garbage Collection,垃圾收集,垃圾回收)机制,是Java与C++/C的主要区别之一,做为Java开发者,通常不须要专门编写内存回收和垃圾清理代码,对内存泄露和溢出的问题,也不须要像C程序员那样战战兢兢。这是由于在Java虚拟机中,存在自动内存管理和垃圾清扫机制。归纳地说,该机制对JVM(Java Virtual Machine)中的内存进行标记,并肯定哪些内存须要回收,根据必定的回收策略,自动的回收内存,永不停息(Nerver Stop)的保证JVM中的内存空间,防止出现内存泄露和溢出问题。java
在Java语言出现以前,就有GC机制的存在,如Lisp语言),Java GC机制已经日臻完善,几乎能够自动的为咱们作绝大多数的事情。然而,若是咱们从事较大型的应用软件开发,曾经出现过内存优化的需求,就一定要研究Java GC机制。程序员
简单总结一下,Java GC就是经过GC收集器回收不在存活的对象,保证JVM更加高效的运转。若是不了解GC算法和垃圾回收器能够参考这篇文章:jvm系列(三):GC算法 垃圾收集器。web
通常状况能够经过两种方式来获取GC日志,一种是使用命令动态查看,一种是在容器中设置相关参数打印GC日志。算法
Java 自动的工具行命令,jstat能够用来动态监控JVM内存的使用,统计垃圾回收的各项信息。tomcat
好比经常使用命令,jstat -gc
统计垃圾回收堆的行为并发
$ jstat -gc 1262
S0C S1C S0U S1U EC EU OC OU PC PU YGC YGCT FGC FGCT GCT
26112.0 24064.0 6562.5 0.0 564224.0 76274.5 434176.0 388518.3 524288.0 42724.7 320 6.417 1 0.398 6.815复制代码
也能够设置间隔固定时间来打印:less
$ jstat -gc 1262 2000 20复制代码
这个命令意思就是每隔2000ms输出1262的gc状况,一共输出20次jvm
更详细的内容参考这篇文章:jvm系列(四):jvm调优-命令篇工具
JVM的GC日志的主要参数包括以下几个:
-XX:+PrintGC
输出GC日志 -XX:+PrintGCDetails
输出GC的详细日志 -XX:+PrintGCTimeStamps
输出GC的时间戳(以基准时间的形式) -XX:+PrintGCDateStamps
输出GC的时间戳(以日期的形式,如 2017-09-04T21:53:59.234+0800) -XX:+PrintHeapAtGC
在进行GC的先后打印出堆的信息 -Xloggc:../logs/gc.log
日志文件的输出路径 在生产环境中,根据须要配置相应的参数来监控JVM运行状况。
咱们常常在tomcat的启动参数中添加JVM相关参数,这里有一个典型的示例:
JAVA_OPTS="-server -Xms2000m -Xmx2000m -Xmn800m -XX:PermSize=64m -XX:MaxPermSize=256m -XX:SurvivorRatio=4 -verbose:gc -Xloggc:$CATALINA_HOME/logs/gc.log -Djava.awt.headless=true -XX:+PrintGCTimeStamps -XX:+PrintGCDetails -Dsun.rmi.dgc.server.gcInterval=600000 -Dsun.rmi.dgc.client.gcInterval=600000 -XX:+UseConcMarkSweepGC -XX:MaxTenuringThreshold=15"复制代码
根据上面的参数咱们来作一下解析:
-Xms2000m -Xmx2000m -Xmn800m -XX:PermSize=64m -XX:MaxPermSize=256m
Xms,即为jvm启动时得JVM初始堆大小,Xmx为jvm的最大堆大小,xmn为新生代的大小,permsize为永久代的初始大小,MaxPermSize为永久代的最大空间。
-XX:SurvivorRatio=4
SurvivorRatio为新生代空间中的Eden区和救助空间Survivor区的大小比值,默认是8,则两个Survivor区与一个Eden区的比值为2:8,一个Survivor区占整个年轻代的1/10。调小这个参数将增大survivor区,让对象尽可能在survitor区呆长一点,减小进入年老代的对象。去掉救助空间的想法是让大部分不能立刻回收的数据尽快进入年老代,加快年老代的回收频率,减小年老代暴涨的可能性,这个是经过将-XX:SurvivorRatio 设置成比较大的值(好比65536)来作到。
-verbose:gc -Xloggc:$CATALINA_HOME/logs/gc.log
将虚拟机每次垃圾回收的信息写到日志文件中,文件名由file指定,文件格式是平文件,内容和-verbose:gc输出内容相同。
-Djava.awt.headless=true
Headless模式是系统的一种配置模式。在该模式下,系统缺乏了显示设备、键盘或鼠标。
-XX:+PrintGCTimeStamps -XX:+PrintGCDetails
设置gc日志的格式
-Dsun.rmi.dgc.server.gcInterval=600000 -Dsun.rmi.dgc.client.gcInterval=600000
指定rmi调用时gc的时间间隔
-XX:+UseConcMarkSweepGC -XX:MaxTenuringThreshold=15
采用并发gc方式,通过15次minor gc 后进入年老代
摘录GC日志一部分
Young GC回收日志:
2016-07-05T10:43:18.093+0800: 25.395: [GC [PSYoungGen: 274931K->10738K(274944K)] 371093K->147186K(450048K), 0.0668480 secs] [Times: user=0.17 sys=0.08, real=0.07 secs]复制代码
Full GC回收日志:
2016-07-05T10:43:18.160+0800: 25.462: [Full GC [PSYoungGen: 10738K->0K(274944K)] [ParOldGen: 136447K->140379K(302592K)] 147186K->140379K(577536K) [PSPermGen: 85411K->85376K(171008K)], 0.6763541 secs] [Times: user=1.75 sys=0.02, real=0.68 secs]复制代码
经过上面日志分析得出,PSYoungGen、ParOldGen、PSPermGen属于Parallel收集器。其中PSYoungGen表示gc回收先后年轻代的内存变化;ParOldGen表示gc回收先后老年代的内存变化;PSPermGen表示gc回收先后永久区的内存变化。young gc 主要是针对年轻代进行内存回收比较频繁,耗时短;full gc 会对整个堆内存进行回城,耗时长,所以通常尽可能减小full gc的次数
经过两张图很是明显看出gc日志构成:
Young GC日志:
Full GC日志:
GChisto是一款专业分析gc日志的工具,能够经过gc日志来分析:Minor GC、full gc的时间、频率等等,经过列表、报表、图表等不一样的形式来反应gc的状况。虽然界面略显粗糙,可是功能仍是不错的。
配置好本地的jdk环境以后,双击GChisto.jar,在弹出的输入框中点击 add 选择gc.log日志
GC Pause Distribution:查看GC停顿的详细分布,x轴表示垃圾收集停顿时间,y轴表示是停顿次数。
GC Timeline:显示整个时间线上的垃圾收集
不过这款工具已经再也不维护
这是一个web工具,在线使用很是方便.
地址: gceasy.io
进入官网,讲打包好的zip或者gz为后缀的压缩包上传,过一会就会拿到分析结果。
推荐使用此工具进行gc分析。
喜欢个人文章,请关注个人公众号