JVM-3-JVM调优

问题

堆大小设置

  • JVM堆大小限制因素
    • 操作系统位数
    • 系统可用物理内存
    • 系统可用虚拟内存
    • x32:Windows一般1.5~2G;Linux 2~3G
    • x64:无限制
  • 典型设置
-Xms3550M -Xmx3550M -Xmn2G -Xss128K 
-XX:NewRatio=4 -XX:SurvivorRatio=8 -XX:PermSize=16M -XX:MaxPermSize=16M -XX:MaxTenuringThreshold=0
  • 参数说明
    • -XX:+PrintHeapAtGC
    • -Xms3550M:JVM初始内存
    • -Xmx3550M:JVM最大内存,等于Xms可避免自扩容和压缩
    • -Xmn2G:年轻代大小
      • JVM内存 = 年轻代 + 年老代 + 永久代
      • 永久代一般固定为64M,增大年轻代后,将会减小年老代;Sun官方推荐配置为整个堆的3/8
    • -Xss128K:每个线程栈大小
      • JDK 5以后每个线程栈大小为1M,以前为256K
      • 相同物理内存下,减小这个值能生成更多的线程;但操作系统对一个进程内的线程数有限制,不能无限生成,经验值在3000~5000左右
    • -XX:NewRatio=4
      • 年轻代与老年代的比例
      • 设置为4,年轻代:老年代为1:4
      • -XX:SurvivorRatio=8
        • Eden与Survivor比例
        • 设置为8,Survivor:Eden为2:8,一个Survivor区占1/10
    • -XX:PermSize=6M:初始永久代大小
    • -XX:MaxPermSize=16M:最大永久代大小
    • -XX:MaxTenuringThreshold=0
      • 年轻代对象最大年龄
      • 设置为0时,年轻代对象不经过Survivor,直接进入年老代
      • 对于老年代对象比较多的应用,可以提高效率
      • 如果设置为一个较大值,则对象会在Survivor区进行多次复制,可以增加对象在年轻代的存活时间,增加在年轻代被回收的概率

收集器选择

  • 串行
    • 小数据量场景
    • JDK 5以前默认,JDK 5开始会自动调整
  • 并行
    • 吞吐量优先
    • 科学计算和后台处理
  • 并发
    • 响应时间优先
    • 应用服务器
  • 并行典型配置
-XX:+UseParallelGC -XX:+UseParallelOldGC -XX:ParallelGCThreads=20
-XX:MaxGCPauseMillis=100 -XX:GCTimeRatio=n -XX:+UseAdaptiveSizePolicy
  • 说明
    • -XX:+UseParallelGC
      • 并行收集器,仅对年轻代有效;年老代仍使用串行
    • -XX:+UseParallelOldGC
      • 年老代并行;JDK 6开始支持
    • -XX:ParallelGCThreads=20
      • 并行收集线程数,最好与处理器数目相等
    • -XX:MaxGCPauseMillis=100
      • 年轻代回收最长时间;若无法满足,JVM会自动调整年轻代大小
    • -XX:GCTimeRatio=n
      • 垃圾收集时间占比1/(n+1)
    • -XX:+UseAdaptiveSizePolicy
      • 并行收集器自动选择年轻代大小和相应的Survivor比例,以达到最低响应时间或收集频率,建议使用并行收集器时一直打开
  • 并发典型配置
-XX:ParallelGCThreads=20 -XX:+UseParNewGC -XX:+UseConcMarkSweepGC
-XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=5 -XX:+CMSIncrementalMode
  • 说明
    • -XX:+UseParNewGC
      • 年轻代并行收集,可与CMS同时使用
      • JDK 5以上,JVM会根据系统配置自行设置,所以无需再设置
    • -XX:+UseConcMarkSweepGC
      • 年老代并发收集
      • 测试中该配置后,-XX:NewRatio=4失效,原因不明;此时年轻代最好用-Xmn设置
    • -XX:+UseCMSCompactAtFullCollection
      • 打开压缩,可能会影响性能
    • -XX:CMSFullGCsBeforeCompaction
      • CMS不进行压缩整理,所以会产生碎片
      • 运行多少次GC后对内存进行压缩整理
    • -XX:+CMSIncrementalMode
      • 并发标记阶段,GC线程会暂停一些间隔,将CPU让给应用线程,已废弃

G1

-XX:+UseG1GC # G1

辅助信息

  • 选项
-XX:+PrintGC
  • 输出
[GC 118250K->113543K(130112K), 0.0094143 secs]
[Full GC 121376K->10414K(130112K), 0.0650971 secs]
  • 选项
-XX:+PrintGCDetails
  • 输出
[GC (System.gc()) [PSYoungGen: 3722K->904K(35840K)] 3722K->912K(117760K), 0.0033150 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC (System.gc()) [PSYoungGen: 904K->0K(35840K)] [ParOldGen: 8K->860K(81920K)] 912K->860K(117760K), [Metaspace: 3476K->3476K(1056768K)], 0.0091323 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 
Heap
 PSYoungGen      total 35840K, used 307K [0x00000000d8600000, 0x00000000dae00000, 0x0000000100000000)
  eden space 30720K, 1% used [0x00000000d8600000,0x00000000d864ce40,0x00000000da400000)
  from space 5120K, 0% used [0x00000000da400000,0x00000000da400000,0x00000000da900000)
  to   space 5120K, 0% used [0x00000000da900000,0x00000000da900000,0x00000000dae00000)
 ParOldGen       total 81920K, used 860K [0x0000000089200000, 0x000000008e200000, 0x00000000d8600000)
  object space 81920K, 1% used [0x0000000089200000,0x00000000892d73e8,0x000000008e200000)
 Metaspace       used 3483K, capacity 4496K, committed 4864K, reserved 1056768K
  class space    used 381K, capacity 388K, committed 512K, reserved 1048576K
  • 选项
-XX:+PrintGCTimeStamps

-输出

11.851: [GC 98328K->93620K(130112K), 0.0082960 secs]
  • 选项
-XX:+PrintGCApplicationConcurrentTime # 每次垃圾回收前,程序未中断的执行时间
  • 输出
Application time: 0.5291524 seconds
  • 选项
-XX:+PrintGCApplicationStoppedTime # 垃圾回收期间程序暂停的时间
  • 输出
Total time for which application threads were stopped: 0.0468229 seconds
  • 选项
-XX:+PrintHeapAtGC # 打印GC前后的详细堆栈信息
  • 输出
{Heap before GC invocations=1 (full 0):
 PSYoungGen      total 35840K, used 3722K [0x00000000d8600000, 0x00000000dae00000, 0x0000000100000000)
  eden space 30720K, 12% used [0x00000000d8600000,0x00000000d89a2908,0x00000000da400000)
  from space 5120K, 0% used [0x00000000da900000,0x00000000da900000,0x00000000dae00000)
  to   space 5120K, 0% used [0x00000000da400000,0x00000000da400000,0x00000000da900000)
 ParOldGen       total 81920K, used 0K [0x0000000089200000, 0x000000008e200000, 0x00000000d8600000)
  object space 81920K, 0% used [0x0000000089200000,0x0000000089200000,0x000000008e200000)
 Metaspace       used 3477K, capacity 4496K, committed 4864K, reserved 1056768K
  class space    used 380K, capacity 388K, committed 512K, reserved 1048576K
Heap after GC invocations=1 (full 0):
 PSYoungGen      total 35840K, used 936K [0x00000000d8600000, 0x00000000dae00000, 0x0000000100000000)
  eden space 30720K, 0% used [0x00000000d8600000,0x00000000d8600000,0x00000000da400000)
  from space 5120K, 18% used [0x00000000da400000,0x00000000da4ea020,0x00000000da900000)
  to   space 5120K, 0% used [0x00000000da900000,0x00000000da900000,0x00000000dae00000)
 ParOldGen       total 81920K, used 8K [0x0000000089200000, 0x000000008e200000, 0x00000000d8600000)
  object space 81920K, 0% used [0x0000000089200000,0x0000000089202000,0x000000008e200000)
 Metaspace       used 3477K, capacity 4496K, committed 4864K, reserved 1056768K
  class space    used 380K, capacity 388K, committed 512K, reserved 1048576K
}
{Heap before GC invocations=2 (full 1):
 PSYoungGen      total 35840K, used 936K [0x00000000d8600000, 0x00000000dae00000, 0x0000000100000000)
  eden space 30720K, 0% used [0x00000000d8600000,0x00000000d8600000,0x00000000da400000)
  from space 5120K, 18% used [0x00000000da400000,0x00000000da4ea020,0x00000000da900000)
  to   space 5120K, 0% used [0x00000000da900000,0x00000000da900000,0x00000000dae00000)
 ParOldGen       total 81920K, used 8K [0x0000000089200000, 0x000000008e200000, 0x00000000d8600000)
  object space 81920K, 0% used [0x0000000089200000,0x0000000089202000,0x000000008e200000)
 Metaspace       used 3477K, capacity 4496K, committed 4864K, reserved 1056768K
  class space    used 380K, capacity 388K, committed 512K, reserved 1048576K
Heap after GC invocations=2 (full 1):
 PSYoungGen      total 35840K, used 0K [0x00000000d8600000, 0x00000000dae00000, 0x0000000100000000)
  eden space 30720K, 0% used [0x00000000d8600000,0x00000000d8600000,0x00000000da400000)
  from space 5120K, 0% used [0x00000000da400000,0x00000000da400000,0x00000000da900000)
  to   space 5120K, 0% used [0x00000000da900000,0x00000000da900000,0x00000000dae00000)
 ParOldGen       total 81920K, used 860K [0x0000000089200000, 0x000000008e200000, 0x00000000d8600000)
  object space 81920K, 1% used [0x0000000089200000,0x00000000892d73e8,0x000000008e200000)
 Metaspace       used 3477K, capacity 4496K, committed 4864K, reserved 1056768K
  class space    used 380K, capacity 388K, committed 512K, reserved 1048576K
}
  • 选项
-Xloggc:filename # 记录日志到文件

调优总结

  • 年轻代大小
    • 响应时间优先
      • 尽可能大,接近系统最低响应时间限制;此种情况下,年轻代收集频率最小;同时,减少到达年老代的对象
    • 吞吐量优先
      • 尽可能大,可能到达GB;因为对响应时间没有要求,垃圾收集可以并行进行,一般适合8CPU以上的应用
  • 老年代大小
    • 响应时间优先
      • 年老代使用并发,所以大小需小心设置,一般要考虑并发会话率和会话持续时间等一些参数;若堆设置小了,可能因高回收频率及碎片引起的空间不足,导致并发收集停止,而使用传统的标记清除方式;如果堆大了,则需要较长的收集时间
    • 吞吐量优先
      • 一般吞吐量优先的应用都有一个很大的年轻代和一个较小的年老代
      • 原因是:尽可能回收掉大部分短期对象,减少中期对象,而年老代仅存放长期存活对象
    • 较小堆引起的碎片问题
      • 年老代并发收集器使用标记清除算法,不会进行压缩
      • 堆空间较小时,运行一段时间出现碎片,并发收集器找不到足够空间,就会停止;然后使用传统的标记清除方式进行回收
      • 若出现碎片,可考虑
        • -XX:+UseCMSCompactAtFullCollection
        • -XX:CMSFullGCsBeforeCompaction=0
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,869评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,716评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,223评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,047评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,089评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,839评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,516评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,410评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,920评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,052评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,179评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,868评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,522评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,070评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,186评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,487评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,162评论 2 356

推荐阅读更多精彩内容