思路:调优一般调的是什么优?
- Heap 中老年代的持续增长触摸到内存红线
- Full GC 次数过多,GC 停顿时间太久
- 解决 OOM
- 本地缓存占用太多内存空间
- 系统整体吞吐量不高
而一些原则也是需要明确的:
- 多数的 Java 应用其实并不需要在服务器上进行 JVM 调优
- 多数的 GC 问题,其实是我们的程序问题。
- 在上线前预调 JVM 至最佳参数
- 对对象进行调整。减少对象的创建,减少全局变量和大对象。
- JVM 调优是最后考虑的事情。
- 分析 GC 情况来调整代码要比调优 JVM 更有效果。
总的来说就是依照这些原则来解决这些问题以达到 GC 低频 GC 停顿时间短,以及低内存占用和高吞吐。
一般的步骤:
一般呢首先要拿到 GC 日志 以及 Dump 文件。来分析判断是否需要优化进而确定瓶颈。然后确定调优参数,应用到一台服务器,观察,之后再应用到所有的
所有的服务器。
参数:
分类
可以简单的分为三类: "-"开头的参数、"-X"开头的参数、"-XX"开头的参数;
"-X"开头的参数是非标准参数,只能被部分VM识别,而不能被全部VM识别的参数;
"-XX"开头的参数是非稳定参数,随时可能被修改或者移除;
常见语法有:
-XX:+[PARAM], 开启该参数的功能,
如-XX:+DisableExplicitGC,开启禁止显式GC
-XX:-[PARAM], 关闭该参数的功能,如-XX:-DisableExplicitGC,关闭禁止显示GC
-XX:PARAM=VALUE, 设置参数的值,
如-XX:SurvivorRatio=80,设置eden/survivor的比值
实例
下图简直是重大利好!因为 Jvm 参数,太多了。懂得都懂。
- Xms 初始堆大小 默认物理内存的1/64(小于1GB)空余堆大小小于40%时,JVM就会增大堆直到-Xmx的最大限制
- Xmx 最大堆大小 默认物理内存的1/4(小于1GB)空余堆大小大于70%时,JVM就会减少堆直到-Xms的最小限制
我们可以通过将“-Xms”和“-Xmx”设置为相同大小来获得一个固定大小的堆内存。 -Xms和-Xmx实际上是-XX:InitialHeapSize和-XX:MaxHeapSize的缩写。我们也可以直接使用这两个参数,它们所起得效果是一样的
- Xmn 年轻代大小
- XX:NewSize 设置年轻代初始大小
- XX:MaxNewSize 年轻代最大值
- XX:PermSize 设置持久代初始值
- XX:MaxPermSize 设置持久代最大值
- Xss 每个线程堆栈大小 JDK5.0以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K,这个参数对影响比较大,需经过严格测试后进行调整
- XX:NewRatio 年轻代(包括Eden和两个Survivor区)与年老代的比值(除去持久代) -XX:NewRatio=4表示年轻代与年老代所占比值为1:4,年轻代占整个堆栈的1/5,Xms=Xmx并且设置了Xmn的情况下,该参数不需要进行设置。
- XX:SurvivorRatio Eden区与Survivor区的大小比值 设置为8,则两个Survivor区与一个Eden区的比值为2:8,一个Survivor区占整个年轻代的1/10
- XX:+HeapDumpOnOutOfMemoryError and -XX:HeapDumpPath 当我们没法为-Xmx(最大堆内存)设置一个合适的大小,那么就有可能面临内存溢出(OutOfMemoryError)的风险,这可能是我们使用JVM时面临的最可怕的猛兽之一导致内存溢出的根本原因需要仔细的定位。通常来说,分析堆内存快照(Heap Dump)是一个很好的定位手段,如果发生内存溢出时没有生成内存快照,特别是对于那种JVM已经崩溃或者错误只出现在顺利运行了数小时甚至数天的生产系统上时,将很难去分析崩溃问题。我们可以通过设置 -XX:+HeapDumpOnOutOfMemoryError 让JVM在发生内存溢出时自动的生成堆内存快照。有了这个参数,当我们不得不面对内存溢出异常的时候会节约大量的时间。默认情况下,堆内存快照会保存在JVM的启动目录下名为java_pid.hprof 的文件里(在这里就是JVM进程的进程号)。也可以通过设置-XX:HeapDumpPath=来改变默认的堆内存快照生成路径, 可以是相对或者绝对路径。