JAVA调优之JVM-GC

JAVA调优之JVM-GC

在分享之前需要给大家说一下,JVM的堆一般分为新生代,老年代永久代这三个区间,下面我们就来说明根据各种情况来进行排查,并对这三个区进行分配合理的区间。

服务器

  • 应用:dal-service-5.1.4.0-SNAPSHOT.jar
  • CPU:24核
  • 内存:125G
  • JDK:8.144
启动应用
1
java -jar ./dal-service-5.1.4.0-SNAPSHOT.jar --spring.profiles.active=test

使用上面的命令,我们的应用就启动完成来,然后我们来看一下应用的各种数据。

  1. 查看应用的PID进程号,使用JPS

  2. 查看CPU和内存情况,可以使用TOP,并按下1

现在应用的基本情况就知道来,但这只是一个基础的信息,怎样能看详细的资源,比如GC怎么回收的,GC触发时间,GC频率等。现在我们把应用停了,加载GC的一些参数和GC的日志,再次启动

1
2
3
4
5
6
7
java \
-verbose:gc \
-XX:+PrintGCDetails \
-XX:+PrintGCTimeStamps \
-XX:+PrintHeapAtGC \
-Xloggc:/home/iot/dal-service-gc.log \
-jar /home/iot/portal/dal-service-5.1.4.0-SNAPSHOT.jar --spring.profiles.active=test
查看GC情况

查看GC情况,有2种方法可以查看

1、直接查看dal-service-gc.log日志文件

2、使用jstatd进行监听,然后通过jvisualvm来查看

1
jstatd -J-Djava.security.policy=/home/iot/jdk1.8.0_131/bin/jstatd.all.policy -J-Djava.rmi.server.hostname=192.168.156.22 -p 1099 -J-Djava.rmi.server.logCalls=true

其实,我们在日志中就看见当应用启动的时候执行来3次FULL GC。

新生代情况:

  • PSYoungGen total 3185152K, used 3185120K
  • eden space 3150848K, 100% used
  • from space 34304K, 99% used

老年代情况:

  • ParOldGen total 1429504K, used 56198K
  • object space 1429504K, 3% used

持久代情况:

  • Metaspace used 74104K, capacity 74936K, committed 75544K, reserved 1116160K
  • class space used 8951K, capacity 9137K, committed 9256K, reserved 1048576K
优化JVM

大家都知道FULL GC一次,将会降低TPS,并且会暂用线程时间。本次优化让应用尽量启动后不再产生FULL GC,我们调整一下启动命令。

调整后,我们虽然进行来GC,但是没有再次执行FULL GC了,这也算调整完成了。

启动命令参数

– GC

1
2
3
4
-XX:+PrintGCDetails    		GC内容
-XX:+PrintGCTimeStamps 输出GC的时间戳(以基准时间的形式)
-XX:+PrintHeapAtGC 在进行GC的前后打印出堆的信息
-Xloggc:../logs/gc.log 日志文件的输出路径

– JVM

1
2
3
4
5
-Xmn						新生代空间大小,此处的大小是(eden+2 survivor space) 
-XX:NewSize 新生代空间大小初始值
-XX:MaxNewSize 新生代空间大小最大值
-XX:MetaspaceSize 持久代初始值
-XX:MaxMetaspaceSize 最大持久代值
Linux调优

修改/etc/sysctl.conf文件,增加

  • net.ipv4.tcp_tw_reuse = 1
  • net.ipv4.tcp_tw_recycle = 1