02.虚拟机调优案例分析

虚拟机调优案例分析

高性能硬件上的程序部署策略

高性能硬件上的程序部署策略.png

补充:64位虚拟机

Java EE方面,企业级应用经常需要使用超过4GB的内存,此时,32位虚拟机将无法满足需求,可是64位虚拟机虽然可以设置更大的内存,却存在以下缺点:

  • 内存问题: 由于指针膨胀和各种数据类型对齐补白的原因,运行于64位系统上的Java应用程序需要消耗更多的内存,通常要比32位系统额外增加10% ~ 30%的内存消耗。
  • 性能问题: 64位虚拟机的运行速度在各个测试项中几乎全面落后于32位虚拟机,两者大概有15%左右的性能差距。

服务系统经常出现卡顿(Full GC时间太长)

首先 jstat -gcutil 观察GC的耗时,jstat -gccapacity 检查内存用量(也可以加上 -verbose:gc 参数获取GC的详细日志,发现卡顿是由于Full GC时间太长导致的,然后 jinfo -v pid,查看虚拟机参数设置,发现 -XX:NewRatio=9,这就是原因:

  • 新生代太小,对象提前进入老年代,触发Full GC
  • 老年代较大,一次Full GC时间较长

可以调小NewRatio的值,尽肯能让比较少的对象进入老年代。

除了Java堆和永久代之外,会占用较多内存的区域

区域 大小调整/说明 内存不足时抛出的异常
直接内存 -XX:MaxDirectMemorySize OutOfMemoryError: Direct buffer memory
线程堆栈 -Xss StackOverflowErrorOutOfMemoryError: unable to create new native thread
Socket缓存区 每个Socket连接都有Receive(37KB)Send(25KB)两个缓存区 IOException: Too many open files
JNI代码 如果代码中使用JNI调用本地库,那本地库使用的内存也不在堆中
虚拟机和GC 虚拟机、GC代码执行要消耗一定内存

GC调优角度解决新生代存活大量对象问题(Minor GC时间太长)

  • Survivor空间去除,让新生代中存活的对象在第一次Minor GC后立刻进入老年代,等到Full GC时再清理。
  • 参数调整方法:
    • -XX:SurvivorRatio=65536
    • -XX:MaxTenuringThreshold=0
    • -XX:AlwaysTenure
上一页