JavaGC是JVM的记录器,它展示了JVM各个分区的性能。什么是JavaGC?Java的GC(GarbageCollection,垃圾收集,垃圾回收)机制是Java与C++/C的主要区别之一。作为Java开发者,一般没有必要去写内存回收和垃圾清理的代码。内存泄漏和溢出的问题不需要像C程序员那样战战兢兢。这是因为在Java虚拟机中,有自动的内存管理和垃圾清理机制。简单来说,这个机制就是在JVM(JavaVirtualMachine)中标记内存,决定哪些内存需要回收。按照一定的回收策略,自动回收内存,保证JVM中的内存永不停止(NerverStop)。防止内存泄漏和溢出问题的空间。在Java语言出现之前,就有了GC机制,比如Lisp语言),Java的GC机制已经日趋完善,几乎可以自动为我们做大部分事情。但是,如果我们从事的是比较大的应用软件的开发,一直有内存优化的需求,那么就必须要研究Java的GC机制。简单概括一下,JavaGC就是通过GC收集器回收非存活的对象,保证JVM更高效的运行。如果不了解GC算法和垃圾收集器,可以参考这篇文章:jvm系列(三):GC算法垃圾收集器。如何获取JavaGC日志一般情况下,获取GC日志有两种方式,一种是使用命令动态查看,另一种是在容器中设置相关参数打印GC日志。动态查看Java自动工具行命令的命令,jstat可以用来动态监控JVM内存的使用情况,收集垃圾回收的各种信息。比如常用命令,jstat-gc统计垃圾回收堆的行为$jstat-gc1262S0CS1CS0US1UECEUOCOUPCPUYGCYGCTFGCFGCTGCT26112.024064.06562.50.0564224.076274.5434176.0388518.3524288.042724.73206.41710.3986.815也可以设置间隔固定时间来打印:$jstat-gc1262200020这个命令意思就是每隔Output1262gcstatusin2000ms,andoutput20timesintotal.Formoredetailedcontent,refertothisarticle:jvmseries(4):jvmtuning-commandsGCparametersThemainparametersoftheGClogofJVMincludethefollowing:-XX:+PrintGCOutputGClog-XX:+PrintGCDetailsOutputGCdetailedlog-XX:+PrintGCTimeStampsOutputGCtimestamp(intheformofbasetime)-XX:+PrintGCDateStampsOutputGCtimestamp(indateform,suchas2017-09-04T21:53:59.234+0800)-XX:+PrintHeapAtGCprintstheheapinformationbeforeandafterGC-Xloggc:../logs/gc.logTheoutputpathofthelogfileisintheproductionenvironment,configurethecorrespondingParameterstomonitortherunningstatusoftheJVM.Tomcat设置示例我们经常在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=256mXms,即jvm启动时jvm初始堆大小,xmx为jvm最大堆大小,xmn为新生代大小,permsize为初代初始大小,MaxPermSize为初代最大空间。-XX:SurvivorRatio=4SurvivorRatio是新生代空间中的Eden区与救援空间中的Survivor区的大小比例。默认是32,也就是说Eden区是Survivor区大小的32倍。请注意,Survivo有两个区域。因此,Survivor实际上占了整个年轻一代的1/34。调低这个参数会增加survivorarea的大小,让对象在survivorarea中停留的时间尽可能长,减少进入老年代的对象数量。移除救援空间的思路是让大部分无法立即回收的数据尽快进入老年代,加快老年代的回收频率,降低老年代暴涨的可能性。这是通过将-XX:SurvivorRatio设置为一个比较大的值(比如65536)来完成的。-verbose:gc-Xloggc:$CATALINA_HOME/logs/gc.log将虚拟机每次垃圾回收的信息写入日志文件,文件名由file指定,文件格式为平面文件,内容与-verbose:gc输出内容相同。-Djava.awt.headless=trueHeadless模式是系统的一种配置模式。在这种模式下,系统缺少显示设备、键盘或鼠标。-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次minorGC后,进入老年代。GC日志如何分析部分GC日志YoungGCrecoverylog:2016-07-05T10:43:18.093+0800:25.395:[GC[PSYoungGen:274931K->10738K(274944K)]371093K->147186K(450048K),0.0668480secs][Times:user=0.17sys=0.08,real=0.07secs]FullGC恢复日志:2016-07-05T10:43:18.160+0800:25.462:[FullGC[PSYoungGen:10738K->0K(274944K)][ParOldGen:136447K->140379K(302592K)]147186K->140379K(577536K)[PSPermGen:85417K->8K(853),0.6763541secs][Times:user=1.75sys=0.062,reals】根据上面的日志分析,PSYoungGen、ParOldGen、PSPermGen属于Parallel收集器。其中,PSYoungGen表示gc回收前后年轻代的内存变化;ParOldGen表示gc回收前后老年代的内存变化;PSPermGen表示gc回收前后***区的内存变化。Younggc主要是针对年轻代的内存回收,比较频繁,耗时较短;fullgc会返回整个堆内存,耗时较长,所以一般尽量减少fullgc的次数。从两张图可以清楚的看出gclog的组成:YoungGClog:FullGClog:GC分析工具GChistoGChisto是一款专业的gc日志分析工具,通过gclogs可以分析出:MinorGC,fullGCtime,频率等,通过列表、报告、图表等形式来反映gc的情况。虽然界面有点粗糙,但是功能还是不错的。配置本地jdk环境后,双击GChisto.jar,在弹出的输入框中点击add,选择gc.loglogGCPauseStats:可以查看GC次数,GC时间,GC开销,***GCtime和MinimumGCtime等,以及对应的直方图GCPauseDistribution:查看GC暂停的详细分布,x轴表示垃圾回收暂停时间,y轴表示暂停次数。GCTimeline:在整个时间线上显示垃圾回收。但是,此工具不再维护。GCEasy是一个在线使用非常方便的网络工具。地址:http://gceasy.io进入官网,说说打包好的zip或者上传后缀为gz的压缩包,稍等片刻就可以得到分析结果。推荐使用该工具进行gc分析。【本文为专栏作家《纯洁的微笑》原创稿件,转载请微信♂联系作者获得授权】点此查看该作者更多好文
