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
旧参数GC情况
120
                                      采样间隔5秒钟
100

80
                                      约35秒执行一次YGC
60
                                      约35秒执行一次FGC
40

20

 0
      41




      73
      77
      81
       5




      33
       9




      37




      57

      65




      93
      69




      97
      53

      61
       1




      25




      85
      29
      21




      45
      13




      49




      89
      17




         S0    S1   E   O   P           新参数GC情况
                                120

      采样间隔5秒钟                   100

      约140秒执行一次YGC              80

      几乎没有FGC                   60

      GC耗时减少96%                 40

                                20

                                 0




                                      81


                                      93
                                      33
                                      37
                                      41




                                      61
                                      65
                                      69
                                      73
                                      77




                                      97
                                       5




                                      53
                                       9




                                      57
                                       1




                                      25




                                      45
                                      29
                                      21




                                      85
                                      89
                                      13
                                      17




                                      49
                                       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         5.0默认false;6.0默认true
-XX:+FailOverToOldVerifier    6.0引入
-XX:+UseBiasedLocking         5.0u6引入,默认false;6.0默认true
-XX:+UseSpinning              5.0默认false;6.0默认true
-XX:PreBlockSpin=10
-XX:+AggressiveOpts           5.0u6引入,默认false;6.0默认true
-XX:+UseLargePages            5.0u5引入,默认false;6.0默认true
-XX:LargePageSizeInBytes=4m
-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/garb
        age_collect.html
   http://blog.dynatrace.com/2011/05/11/how-garbage-collection-differs-in-
    the-three-big-jvms/

   感谢Bluedavy与RednaxelaFX
实战HotSpot JVM GC

实战HotSpot JVM GC

  • 1.
  • 2.
    Load  CPU  MEM  IO  响应时间  吞吐量  JVM——YGC、FGC次数与时间  ……
  • 4.
    JVM内存划分  JVM分析相关工具  命令行常用参数  HotSpot GC策略  优化案例分析  优化建议  其他
  • 5.
    局部变量区 本地方法栈 PC寄 操作数栈 存器 栈帧 JVM方法区 JVM方法栈 JVM堆  PC寄存器  栈:JVM方法栈、本地方法栈  JVM方法区  JVM堆
  • 6.
    新生代Young/New (Eden, S0, S1)  旧生代Tenured  持久代Perm
  • 7.
    JVM内存划分  JVM分析相关工具  命令行常用参数  HotSpot GC策略  优化案例分析  优化建议  其他
  • 8.
    jps  jinfo  JConsole  VisualVM ( http://visualvm.java.net/ )  jstat ( http://docs.oracle.com/javase/1.5.0/docs/tooldocs/share/jstat.html )
  • 9.
    jstat <选项> <pid> [间隔时间 ] [总次数]  -gccapacity  -gccause  -gcutil  pid not found怎么办?(/tmp/hsperfdata_用户名/vmid)
  • 10.
    kill -3  jstack  jmap ( http://docs.oracle.com/javase/1.5.0/docs/tooldocs/share/jmap.html )  Eclipse MAT ( http://www.eclipse.org/mat/ )
  • 12.
    dump  分析
  • 13.
    JVM内存划分  JVM分析相关工具  命令行常用参数  HotSpot GC策略  优化案例分析  优化建议  其他
  • 14.
    -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
  • 15.
    GC监控相关  -Xloggc: 文件  -XX:+PrintGCDetails  -XX:+PrintGCTimeStamps  -XX:+PrintGCDateStamps(jdk6u4)  -XX:+PrintFlagsFinal(jdk6u21)  -XX:-PrintCommandLineFlags
  • 16.
    JVM内存划分  JVM分析相关工具  命令行常用参数  HotSpot GC策略  优化案例分析  优化建议  其他
  • 17.
    Minor GC  Serial Copying  ParNew  Parallel Scavenge  Major GC  Serial  Parallel  CMS
  • 18.
    Serial Copying  -XX:+UseSerialGC  Client模式默认
  • 19.
    Parallel Scavenge  -XX:+UseParallelGC  -XX:-UseAdaptiveSizePolicy  -XX:ParallelGCThreads  Server模式默认
  • 20.
    ParNew  -XX:+UseParNewGC  CMS默认,针对CMS做了特殊处理  不可与并行旧生代GC共用
  • 21.
    Serial  Mark-Sweep-Compact  -XX:+UseSerialGC  Parallel  Mark-(Summary)-Compact  -XX:+UseParallelOldGC
  • 22.
    Concurrent Mark-Sweep(CMS)  并行?并发?
  • 23.
    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
  • 24.
    CMS时有两种情况需要关注  promotion failed  Minor GC时Survivor放不下,旧生代也放不下  concurrent mode failure  CMS过程中有对象要放入旧生代,但空间不足  需要根据情况调整各区比例
  • 26.
    触发条件:  旧生代空间不足  PermGen空间不足  promotion failed / concurrent mode failure  统计到MinorGC平均晋升大小大于旧生代剩余空间
  • 27.
    GC监控相关(续)  -XX:+PrintTenuringDistribution  -XX:+PrintGCApplicationStoppedTime  -XX:+TraceClassLoading  -XX:+TraceClassUnloading  Dump  -XX:+HeapDumpOnOutOfMemoryError(jdk5u7)  -XX:+HeapDumpOnCtrlBreak(jdk5u14)  -XX:+HeapDumpBeforeFullGC  -XX:HeapDumpPath=路径
  • 28.
  • 29.
    GC对象晋升相关  -XX:SurvivorRatio  -XX:PretenureSizeThreshold=0  -XX:InitialTenuringThreshold=7  -XX:MaxTenuringThreshold=15  -XX:-UseAdaptiveSizePolicy  -XX:+DisableExplicitGC  -XX:ErrorFile=./hs_err_pid<pid>.log(jdk6)
  • 30.
    JVM内存划分  JVM分析相关工具  命令行常用参数  HotSpot GC策略  优化案例分析  优化建议  其他
  • 31.
    开始前  基线数据收集  设定目标  进行中  修改配臵  数据对比  结束后  单机配臵  集群配臵  总结
  • 32.
    案例1:堆大小配臵造成GC频繁  -Xms768m -Xmx1280m -Xmn128m  -XX:PermSize=96m -XX:MaxPermSize=128m  -XX:SurvivorRatio=20000  -XX:+UseConcMarkSweepGC -XX:+UseParNewGC
  • 33.
    问题  应该避免堆大小缩放  堆大小偏小  新生代过小  不该取消Survivor区  调整  -Xms1600m -Xmx1600m -Xmn600m  -XX:PermSize=128m -XX:MaxPermSize=128m  -XX:SurvivorRatio=22 -XX:MaxTenuringThreshold=6  -XX:+UseConcMarkSweepGC -XX:+UseParNewGC
  • 34.
    旧参数GC情况 120 采样间隔5秒钟 100 80 约35秒执行一次YGC 60 约35秒执行一次FGC 40 20 0 41 73 77 81 5 33 9 37 57 65 93 69 97 53 61 1 25 85 29 21 45 13 49 89 17 S0 S1 E O P 新参数GC情况 120 采样间隔5秒钟 100 约140秒执行一次YGC 80 几乎没有FGC 60 GC耗时减少96% 40 20 0 81 93 33 37 41 61 65 69 73 77 97 5 53 9 57 1 25 45 29 21 85 89 13 17 49 S0 S1 E O P
  • 35.
    案例2:concurrent mode failure  -Xmx1280m -Xmn128m  存在一个尾递归,遇到大请求不断创建对象  症状:CPU飙高,系统无响应  调整:  -Xmx1800,调整堆大小,让系统完成调用,回 收资源  根本办法,去掉尾递归
  • 36.
    情况模拟  递归  循环
  • 37.
    java -Xmx105m -Xms105m-Xmn30m -XX:SurvivorRatio=20000 -XX:MaxTenuringThreshold=0 -XX:+UseConcMarkSweepGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps ConcurrentModeFailure 递归 循环
  • 38.
    案例3:YGC造成Full GC频繁  JDK5  -Xms1800m -Xmx1800m -Xmn680m  -XX:PermSize=240m -XX:MaxPermSize=240m  -XX:+UseConcMarkSweepGC -XX:+UseParNewGC 注意各区占用比例
  • 39.
    问题  存在concurrent mode failure  几乎每次YGC都会触发一次FGC  调整  -XX:+HandlePromotionFailure  -XX:PermSize=128m -XX:MaxPermSize=128m  -XX:+CMSParallelRemarkEnabled  -XX:+UseCMSInitiatingOccupancyOnly  -XX:CMSInitiatingOccupancyFraction=65  -XX:SurvivorRatio=8
  • 40.
    效果  统计范围,一天  调整前 ▪ YGC 1177次,总耗时44.65秒 ▪ FGC 2177次,总耗时820.95秒  调整后 ▪ YGC 1359次,总耗时45.80秒 ▪ FGC 4次,总耗时0.41秒 ▪ GC总耗时缩短95%
  • 41.
    案例4:神出鬼没的System.gc()  代码中并未出现System.gc()的调用  有可能是依赖的库在调用System.gc()  调整:-XX:+DisableExplicitGC
  • 42.
    JVM内存划分  JVM分析相关工具  命令行常用参数  HotSpot GC策略  优化案例分析  优化建议  其他
  • 43.
    堆大小  32位,最大内存4G,堆的大小不要超过2G  推荐比例  新生代大小最好是最大堆大小的3/8  Survivor比例适中  避免promotion failed和concurrent mode failure  此时会采用串行GC  调整各区比例,CMSInitiatingOccupancyFraction
  • 44.
    使用较新版本的JDK  使用较新版本的OS(至少要打补丁)  输出必要的性能日志  环境变化时,检查JVM参数是否依然合适
  • 45.
    参数 说明 -XX:+HandlePromotionFailure 5.0默认false;6.0默认true -XX:+UseSplitVerifier 5.0默认false;6.0默认true -XX:+FailOverToOldVerifier 6.0引入 -XX:+UseBiasedLocking 5.0u6引入,默认false;6.0默认true -XX:+UseSpinning 5.0默认false;6.0默认true -XX:PreBlockSpin=10 -XX:+AggressiveOpts 5.0u6引入,默认false;6.0默认true -XX:+UseLargePages 5.0u5引入,默认false;6.0默认true -XX:LargePageSizeInBytes=4m -XX:+UseCompressedStrings 6.0u21,默认true -XX:+OptimizeStringConcat 6.0u20,默认true
  • 46.
    JVM内存划分  JVM分析相关工具  命令行常用参数  HotSpot GC策略  优化案例分析  优化建议  其他
  • 47.
    Garbage First  目标:尽量减少GC导致的应用暂停时间,同时 保持堆空间的利用率  分代,将堆分成多个固定大小的Region  始终执行Compact,消除碎片  回收时估算回收成本和价值,价值大的先回收  -XX:+UnlockExperimentalVMOptions -XX:+UseG1GC  -XX:MaxGCPauseMillis =50  -XX:GCPauseIntervalMillis =200
  • 48.
    步骤  初始标记(Initial Marking)  并发标记(Concurrent Marking)  最终标记(Final Marking)  筛选回收(Live Data Counting and Evacuation)
  • 49.
    Oracle JRockit  分代堆  连续堆  Mostly Concurrent Mark and Sweep ▪ Sweep阶段分两次执行,一次清除一半,两次小暂停
  • 50.
    IBM JVM  分代堆  连续堆
  • 51.
    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/garb age_collect.html  http://blog.dynatrace.com/2011/05/11/how-garbage-collection-differs-in- the-three-big-jvms/  感谢Bluedavy与RednaxelaFX