52
DigitalSonic 2012-04

实战HotSpot JVM GC

Embed Size (px)

DESCRIPTION

针对HotSpot JVM GC相关的内容,包括JVM内存划分、JVM分析相关工具、命令行常用参数、HotSpot GC策略、优化案例分析和优化建议等。

Citation preview

DigitalSonic 2012-04

Load CPU MEM IO 响应时间 吞吐量 JVM——YGC、FGC次数与时间 ……

JVM内存划分 JVM分析相关工具 命令行常用参数 HotSpot GC策略 优化案例分析 优化建议 其他

PC寄存器 栈:JVM方法栈、本地方法栈 JVM方法区 JVM堆

PC寄存器

局部变量区

操作数栈

栈帧

JVM方法栈 JVM堆

本地方法栈

JVM方法区

新生代Young/New (Eden, S0, S1) 旧生代Tenured 持久代Perm

JVM内存划分 JVM分析相关工具 命令行常用参数 HotSpot GC策略 优化案例分析 优化建议 其他

jps jinfo JConsole VisualVM ( http://visualvm.java.net/ )

jstat ( http://docs.oracle.com/javase/1.5.0/docs/tooldocs/share/jstat.html )

jstat <选项> <pid> [间隔时间 ] [总次数] -gccapacity

-gccause

-gcutil

pid not found怎么办?(/tmp/hsperfdata_用户名/vmid)

kill -3 jstack

jmap ( http://docs.oracle.com/javase/1.5.0/docs/tooldocs/share/jmap.html )

Eclipse MAT ( http://www.eclipse.org/mat/ )

dump

分析

JVM内存划分 JVM分析相关工具 命令行常用参数 HotSpot GC策略 优化案例分析 优化建议 其他

-server 堆相关

-Xms -Xmx

-Xmn

-XX:PermSize -XX:MaxPermSize

JMX相关 -Dcom.sun.management.jmxremote.port=9981

-Dcom.sun.management.jmxremote.ssl=false

-Dcom.sun.management.jmxremote.authenticate=false

GC监控相关

-Xloggc: 文件

-XX:+PrintGCDetails

-XX:+PrintGCTimeStamps

-XX:+PrintGCDateStamps(jdk6u4)

-XX:+PrintFlagsFinal(jdk6u21)

-XX:-PrintCommandLineFlags

JVM内存划分 JVM分析相关工具 命令行常用参数 HotSpot GC策略 优化案例分析 优化建议 其他

Minor GC

Serial Copying

ParNew

Parallel Scavenge

Major GC

Serial

Parallel

CMS

Serial Copying

-XX:+UseSerialGC

Client模式默认

Parallel Scavenge

-XX:+UseParallelGC

-XX:-UseAdaptiveSizePolicy

-XX:ParallelGCThreads

Server模式默认

ParNew

-XX:+UseParNewGC

CMS默认,针对CMS做了特殊处理

不可与并行旧生代GC共用

Serial

Mark-Sweep-Compact

-XX:+UseSerialGC

Parallel

Mark-(Summary)-Compact

-XX:+UseParallelOldGC

Concurrent Mark-Sweep(CMS) 并行?并发?

CMS -XX:+UseConcMarkSweepGC

-XX:+CMSClassUnloadingEnabled

-XX:+UseCMSInitiatingOccupancyOnly

-XX:CMSInitiatingOccupancyFraction=68(5.0) /92(6.0)

-XX:+UseCMSCompactAtFullCollection

-XX:CMSFullGCsBeforeCompaction=0

-XX:+CMSParallelRemarkEnabled

-XX:+CMSMaxAbortablePrecleanTime=5000

-XX:ParallelCMSThreads

CMS时有两种情况需要关注

promotion failed

Minor GC时Survivor放不下,旧生代也放不下

concurrent mode failure

CMS过程中有对象要放入旧生代,但空间不足

需要根据情况调整各区比例

触发条件: 旧生代空间不足

PermGen空间不足

promotion failed / concurrent mode failure

统计到MinorGC平均晋升大小大于旧生代剩余空间

GC监控相关(续) -XX:+PrintTenuringDistribution

-XX:+PrintGCApplicationStoppedTime

-XX:+TraceClassLoading

-XX:+TraceClassUnloading

Dump -XX:+HeapDumpOnOutOfMemoryError(jdk5u7)

-XX:+HeapDumpOnCtrlBreak(jdk5u14)

-XX:+HeapDumpBeforeFullGC

-XX:HeapDumpPath=路径

-XX:+PrintTenuringDistribution -XX:+TraceClassLoading

GC对象晋升相关 -XX:SurvivorRatio -XX:PretenureSizeThreshold=0 -XX:InitialTenuringThreshold=7 -XX:MaxTenuringThreshold=15 -XX:-UseAdaptiveSizePolicy

-XX:+DisableExplicitGC -XX:ErrorFile=./hs_err_pid<pid>.log(jdk6)

JVM内存划分 JVM分析相关工具 命令行常用参数 HotSpot GC策略 优化案例分析 优化建议 其他

开始前 基线数据收集

设定目标 进行中 修改配臵

数据对比 结束后 单机配臵

集群配臵

总结

案例1:堆大小配臵造成GC频繁 -Xms768m -Xmx1280m -Xmn128m

-XX:PermSize=96m -XX:MaxPermSize=128m

-XX:SurvivorRatio=20000

-XX:+UseConcMarkSweepGC -XX:+UseParNewGC

问题 应该避免堆大小缩放

堆大小偏小

新生代过小

不该取消Survivor区

调整 -Xms1600m -Xmx1600m -Xmn600m

-XX:PermSize=128m -XX:MaxPermSize=128m

-XX:SurvivorRatio=22 -XX:MaxTenuringThreshold=6

-XX:+UseConcMarkSweepGC -XX:+UseParNewGC

采样间隔5秒钟 约140秒执行一次YGC 几乎没有FGC GC耗时减少96%

采样间隔5秒钟 约35秒执行一次YGC 约35秒执行一次FGC

0

20

40

60

80

100

120

1 5 9

13

17

21

25

29

33

37

41

45

49

53

57

61

65

69

73

77

81

85

89

93

97

旧参数GC情况

S0 S1 E O P

0

20

40

60

80

100

120 1 5 9

13

17

21

25

29

33

37

41

45

49

53

57

61

65

69

73

77

81

85

89

93

97

新参数GC情况

S0 S1 E O P

案例2:concurrent mode failure

-Xmx1280m -Xmn128m

存在一个尾递归,遇到大请求不断创建对象

症状:CPU飙高,系统无响应

调整:

-Xmx1800,调整堆大小,让系统完成调用,回收资源

根本办法,去掉尾递归

情况模拟

递归

循环

java -Xmx105m -Xms105m -Xmn30m -XX:SurvivorRatio=20000 -XX:MaxTenuringThreshold=0

-XX:+UseConcMarkSweepGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps

ConcurrentModeFailure

递归 循环

案例3:YGC造成Full GC频繁 JDK5

-Xms1800m -Xmx1800m -Xmn680m

-XX:PermSize=240m -XX:MaxPermSize=240m

-XX:+UseConcMarkSweepGC -XX:+UseParNewGC

注意各区占用比例

问题

存在concurrent mode failure

几乎每次YGC都会触发一次FGC

调整 -XX:+HandlePromotionFailure

-XX:PermSize=128m -XX:MaxPermSize=128m

-XX:+CMSParallelRemarkEnabled

-XX:+UseCMSInitiatingOccupancyOnly

-XX:CMSInitiatingOccupancyFraction=65

-XX:SurvivorRatio=8

效果

统计范围,一天

调整前

▪ YGC 1177次,总耗时44.65秒

▪ FGC 2177次,总耗时820.95秒

调整后

▪ YGC 1359次,总耗时45.80秒

▪ FGC 4次,总耗时0.41秒

▪ GC总耗时缩短95%

案例4:神出鬼没的System.gc()

代码中并未出现System.gc()的调用

有可能是依赖的库在调用System.gc()

调整:-XX:+DisableExplicitGC

JVM内存划分 JVM分析相关工具 命令行常用参数 HotSpot GC策略 优化案例分析 优化建议 其他

堆大小

32位,最大内存4G,堆的大小不要超过2G

推荐比例

新生代大小最好是最大堆大小的3/8

Survivor比例适中

避免promotion failed和concurrent mode failure

此时会采用串行GC

调整各区比例,CMSInitiatingOccupancyFraction

使用较新版本的JDK 使用较新版本的OS(至少要打补丁) 输出必要的性能日志 环境变化时,检查JVM参数是否依然合适

参数 说明

-XX:+HandlePromotionFailure 5.0默认false;6.0默认true

-XX:+UseSplitVerifier -XX:+FailOverToOldVerifier

5.0默认false;6.0默认true 6.0引入

-XX:+UseBiasedLocking 5.0u6引入,默认false;6.0默认true

-XX:+UseSpinning -XX:PreBlockSpin=10

5.0默认false;6.0默认true

-XX:+AggressiveOpts 5.0u6引入,默认false;6.0默认true

-XX:+UseLargePages -XX:LargePageSizeInBytes=4m

5.0u5引入,默认false;6.0默认true

-XX:+UseCompressedStrings 6.0u21,默认true

-XX:+OptimizeStringConcat 6.0u20,默认true

JVM内存划分 JVM分析相关工具 命令行常用参数 HotSpot GC策略 优化案例分析 优化建议 其他

Garbage First

目标:尽量减少GC导致的应用暂停时间,同时保持堆空间的利用率

分代,将堆分成多个固定大小的Region

始终执行Compact,消除碎片

回收时估算回收成本和价值,价值大的先回收

-XX:+UnlockExperimentalVMOptions -XX:+UseG1GC

-XX:MaxGCPauseMillis =50

-XX:GCPauseIntervalMillis =200

步骤

初始标记(Initial Marking)

并发标记(Concurrent Marking)

最终标记(Final Marking)

筛选回收(Live Data Counting and Evacuation)

Oracle JRockit

分代堆

连续堆

Mostly Concurrent Mark and Sweep

▪ Sweep阶段分两次执行,一次清除一半,两次小暂停

IBM JVM

分代堆

连续堆

Oracle/Sun

http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html

http://www.oracle.com/technetwork/java/tuning-139912.html

http://www.oracle.com/technetwork/java/gc-tuning-5-138395.html

http://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html

https://blogs.oracle.com/poonam/entry/understanding_cms_gc_logs

http://www.oracle.com/technetwork/java/javase/tech/g1-intro-jsp-135488.html

http://docs.oracle.com/cd/E13150_01/jrockit_jvm/jrockit/geninfo/diagnos/garbage_collect.html

http://blog.dynatrace.com/2011/05/11/how-garbage-collection-differs-in-the-three-big-jvms/

感谢Bluedavy与RednaxelaFX