简介

通过压力测试查看xwiki的gc情况,统计分析gc日志,在不改变总内存使用的情况下做出合理调整,通过压力测试聚合报告对比调优效果。

步骤

  1. 运行程序,增加打印GC日志的参数;
  2. 使用badboy + jmeter对web程序的单个页面(首页)进行压力测试,压力测试参数为10线程,每线程执行100次测试;
  3. 使用jstatd + jvisualVM实时查看或gcviewer分析GC日志;
  4. 根据分析结果,调整JVM参数;
  5. 分析结果达到预期,结束,否则继续执行1~4。

工具

  • Badboy - 录制jmeter脚本
  • Jmeter - 压力测试
  • Jstatd - 提供远程使用jvisualVM实时看gc情况服务
  • jvisualVM - 查看gc情况
  • Gcviewer - 分析GC日志

测试环境

虚拟机 CPU 8核,内存 8G 操作系统 CentOS6.5 JDK: 1.7

第一轮:使用默认参数

运行web

JVM参数

-Xmx512m -XX:MaxPermSize=196m -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:$LOGSDIR/xwiki.gc -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=1 -XX:GCLogFileSize=512M -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${LOGSDIR}

总内存:512 + 196 = 708M

结果

jstatd + jvisualVM实时:

java 吞吐量限制_操作系统

GCViwer:

java 吞吐量限制_操作系统_02

java 吞吐量限制_压力测试_03

java 吞吐量限制_python_04

聚合报告

java 吞吐量限制_java 吞吐量限制_05

统计分析GC日志: awk '{print $5,$6}' target.0 | awk -F'(' '{print $1,$2}' | awk '{print $1,$3}' | awk -F'->' '{print $1,$2,$3}' | awk -F'K' '{print $1,$2,$3,$4}' | awk '{print ($3-$4)/$1}' | awk '{sum+=$1} END{print sum/NR}' 平均年轻代的回收率为72%, 最差的回收率也基本大于65% 平均每次young GC 堆回收的内存空间为95M, 溢出到老年代的空间为16M 分析full gc每次的存活对象空间大概在170M左右

第二轮 - 调整jvm参数减少Full GC

调整

设置老年代大小为170M × 1.5 = 255M 新生代设置为170M × 2 = 340M

根据回收率计算Eden和Survivor的比例 设eden空间大小为E 设survivor大小为S 则有: E+2*S=340; S/S+E=0.35; -- 假设年轻代回收率为65% 计算得,E:S=1.8:1 则取值2:1

eden:survivor = 2:1

堆空间255+340=595M 永久代 708 - 595 = 113M

JVM参数

-Xmx595M -Xms595M -XX:NewSize=340M -XX:MaxNewSize=340M -XX:SurvivorRatio=2 -XX:PermSize=113M -XX:MaxPermSize=113M -XX:-UseAdaptiveSizePolicy -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:$LOGSDIR/xwiki.gc -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=1 -XX:GCLogFileSize=512M -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${LOGSDIR}

结果

jvisualVM:

java 吞吐量限制_awk_06

gcviewer:

java 吞吐量限制_java 吞吐量限制_07

java 吞吐量限制_操作系统_08

java 吞吐量限制_压力测试_09

聚合报告

java 吞吐量限制_操作系统_10

再次对比测试

10线程,每线程1000次

聚合报告对比

  • 调优前

java 吞吐量限制_操作系统_11

  • 调优后

java 吞吐量限制_awk_12