Java GC

什么是Java GC

Java GC(Garbage Collection,垃圾收集,垃圾回收)机制,一般不需要转本编写内存回收和垃圾清理代码,这是因为在Java虚拟机中,存在自动内存管理和垃圾清扫机制。概括的说,该机制对JVM(Java Virtual Machine)中的内存进行标记,并确定哪些内存需要回收,根据一定的回收策略,自动的回收内存,永不停息的保证JVM中的内存空间,防止出现内存泄漏和溢出问题。

Java GC 就是通过GC收集器回收不再存活的对象,保证JVM更加高效的运转。

如何获取Java GC日志

一般情况可以通过两种方式来获取GC日志,一种是使用命令动态查看,一种是在容器中设置相关参数打印GC日志。

使用命令动态查看

jstat可以用来动态监控JVM内存的使用,统计垃圾回收的各项信息。比如常用命令:jstat -gc pid统计垃圾回收堆的行为

也可以设置间隔固定时间来打印:

 这个命令的意思就是每隔2000ms输出pid 17953的gc情况,一共输出20次。

GC参数

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参数设置示例

我们经常在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区的大小比值,默认是32,也就是说Eden区是Survivor区的32倍大小,要注意Survivo是分为两个区的。调小这个参数将增大survivor区,让对象尽量在survivor区待的久一些,减少进入老年代的对象。

-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次gc后进入到老年代。

如何分析GC日志

Young GC回收日志:

[GC [PSYoungGen: 274931K->10738K(274944K)] 371093K->147186K(450048K), 0.0668480 secs] [Times: user=0.17 sys=0.08, real=0.07 secs]

Full GC回收日志:

[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回收前后年轻代的内存变化;PerOldGen表示gc回收前后老年代的内存变化;PSPermGen表示gc会收钱前后永久代的内存变化。Young GC主要是针对年轻代进行内存回收比较频繁,耗时短;full gc会对整个堆内存进行回收,耗时长。因此一般尽量减少full gc的次数。

 



posted @ 2018-12-17 11:50  sssss-T  阅读(116)  评论(0)    收藏  举报