169°

jvm调优

1.jvm运行模式

  • client模式:启动快,占用内存少,jit编译器生成代码的速度也更快.
  • server模式:主要优势在于代码优化功能,这个功能对于服务器应用而言尤其重要.
  • tiered server模式:结合了client与server的长处,即快速启动和高效的生成代码.通过-server -XX:+TieredCompilation启用

2. 32/64位jvm--linux机器

  • java堆小于2GB,选择32位jvm
  • java堆介于2GB于32GB之间,使用-d64 -XX:+UseCompressedOops命令选项的64位jvm
  • java堆大于32GB,使用-d64选项的64位jvm

3. hotspot内存分配

  • -Xms<n>[g|m|k]:java堆最小值
  • -Xmx<n>[g|m|k]:java堆最大值.关注吞吐量及延迟的java应用程序应该将-Xmx与-Xms设置为同一值,因为无论扩展还是缩减新生代空间或老年代空间,都需要进行Full GC.
  • -XX:NewSize=<n>[g|m|k]:新生代空大小的初始值,也是最小值.指定此项时,应同时指定-XX:MaxNewSize=<n>[g|m|k]
  • -XX:MaxNewSize=<n>[g|m|k]:新生代空间大小的最大值,指定此项时,应同时指定-XX:NewSize=<n>[g|m|k]
  • -Xmn<n>[g|m|k]:设置新生代空间的初始值/最小值/最大值.新生代的大小会根据该值设定.需要注意的是,如果-Xms和-Xmx并没设置为同一值,使用-Xmn时,java堆变化不会影响新生代空间,即新生代空间的大小总保持恒定.
  • -XX:PermSize=<n>[g|m|k]:永久代空间的初始值及最小值
  • -XX:MaxPermSize=<n>[g|m|k]:永久代空间的最大值

4. java堆内存分配规则

在应用程序到达稳定后,可多次进行Full GC,查看java内存使用情况,统计java程序的活跃数据.可使用Jvisualvm进行Full GC,查看gc日志或Jvisualvm的visual gc插件查看应用程序内存使用情况,获取内存空间占有量.

java堆大小计算法则:

空间 命令行选项 占用倍数
java堆 -Xms和-Xmx 3-4倍full gc后的老年代空间占用量
永久代 -XX:PermSize,-XX:MaxPermSize 1.2-1.5倍full gc后的永久代空间占用量
新生代 -Xmn 1-1.5倍full gc后的老年代空间占用量
老年代 java堆大小减新生代大小 2-3倍full gc后的老年代空间占用量

注:这一步分配的内存并不一定达到预期,可继续优化新生代/老年代等.

5. 优化新生代的大小

分析gc数据,

  • 如果发现minor gc的间隔时间过长,则减少新生代的空间;
  • 如果发现minor gc的频率太高,则加大新生代空间.

准则:

  • 老年代空间大小不应该小于活跃数据大小的1.5倍.
  • 新生代空间至少应为java堆大小的10%,通过-Xmx和-Xms可以设定该值.
  • 增大java堆大小时,需要注意不要超过jvm可用的物理内存数.

6. 优化老年代大小

如果预测或观测到full gc的频率不能达到应用程序的最差full gc频率要求,就应该增大老年代空间的大小.

增加老年代空间的大小时,注意保持新生代空间大小的恒定,即增加java堆大小,使用-Xms和-Xmx设定.

7. 为cms调优延迟

调优cms收集器的目的是避免发生stop-the-world的压缩式GC.

从Throughput收集器迁移到cms收集器时需要遵守一个通用原则是,将老年代空间增大20%~30%,这样才能更有效地运行cms收集器.

8. survivor空间

  • survivor空间大小设置:-XX:SurvivorRatio=<ratio>
  • survivor空间大小=-Xmn<value>/(-XX:SurvivorRatio=<ratio> + 2)

调整survivor空间需要保持时应保持eden空间大小不变,应同时调整java堆大小及新生代大小.

例:现有如下配置:
-Xmx1536m -Xms1536m -Xmn512m -XX:SurvivorRatio=30

经计算,得

  • survivor=512/(30+2)=16m
  • eden=16*30=480m

现在需要调整survivor大小到32m,调整方式如下:

-Xmx1568m -Xms1568m -Xmn544m -XX:SurvivorRatio=15

若不调整java堆大小及新生代大小,仅调整-XX:SurvivorRatio数值,会减少eden空间大小,将导致更加频繁的minor gc.

9. 晋升阈值

  • 设置命令:-XX:MaxTenuringThreshold=<n>
  • 输出晋升信息:-XX:PrintTenuringDistribugion

10. 初始化cms收集周期,减少stop-the-world

一般情况下,hotspot vm会尝试自适应计算空间占用多大时开启cms收集周期,但有时并不能避免stop-the-world压缩式垃圾收集(gc日志中会出现concurrent mode failure),此时可以使用以下命令行选项使cms更早地进行垃圾收集:

  • -XX:CMSInitiatingOccupancyFraction=<percent> 设定的值表示cms在老年代空间占用达到多少百分比时启动.数值大小应大于老年代占用空间和活跃数据大小之比.

使用以上命令行选项时,需要结合以下命令行一起使用:

  • -XX:+UseCMSInitiatingOccupancyOnly

若不使用该命令,则cms仅第一次使用-XX:CMSInitiatingOccupancyFraction设定的百分比,以后的周期中又转向自适用地启用cms周期.

11. 初始化cms永久代垃圾收集

gc日志中,cms垃圾收集器使用CMS Perm标识永久代的收集.

一般情况下,cms默认不对永久代进行垃圾收集,可以使用以下命令行选项开启cms的永久代垃圾收集:

  • -XX:+CMSClassUnloadingEnabled

同时也可以指定永久代空间占用比例达到多少时启动cms永久代垃圾收集:

  • -XX:CMSInitiatingPermOccupancyFraction=<percent>
  • -XX:+UseCMSInitiatingOccupancyOnly

本文由【Funcy1122】发布于开源中国,原文链接:https://my.oschina.net/funcy/blog/1929289

全部评论: 0

    我有话说: