原文链接:https://mp.weixin.qq.com/s/oFjubN6qMK8ZhaPNlrA0KQ
1 GC策略调优
- 能够忍受full gc的停顿?
是:选择throughput
否:如果堆较小,使用CMS或者G1;如果堆较大,选择G1。
- 使用默认配置能达到期望目标吗?
首先尽量使用默认配置,因为垃圾收集技术在不断发展成熟,自动优化大多数的效果是最好的。如果默认配置没有达到期望,请确认垃圾收集是否是性能瓶颈。如负荷较高的应用,如果垃圾收集上的时间不超过3%,即使进行垃圾回收调优效果也不大。
- 应用的停顿时间和预期的目标接近吗?
是:调整最大停顿时间设定可能是需要做的
否:需要进行其他调整
如果停顿时间太长,但是吞吐量正常,可以尝试减少新生代大小(如果是full gc,则减少老年代大小),这样停顿时间变短,但是单次时间变长。
- GC停顿很短了,但是吞吐量上不去?
增大堆的大小,但是单次停顿时间会加长。
- 使用并发收集器,发生了由并发模式失败引发的full gc?
如果CPU资源充足,可以增加并发GC的线程数数。
- 使用并发收集器,发生由晋升失败引起的full gc?
如果是CMS,意味着发生了碎片化,这种情况下:使用跟大的堆;尽早启动后台回收;如果堆空间较大,可以选择使用G1。
3 JIT调优
- 一般只需要选择是使用客户端版或者服务器版的JIT编译器即可。
- 客户端版的JIT编译器使用:-client指定,服务器版的使用:-server。
- 选择哪种类型一般和硬件的配置相关,当然随着硬件的发展,也没有一个确定的标准哪种硬件适合哪种配置。
- 两种JIT编译器的区别:
1)Client版对于代码的编译早于Server版,也意味着代码的执行速度在程序执行早期Client版更快。
2)Server版对代码的编译会稍晚一些,这是为了获取到程序本身的更多信息,以便编译得到优化程度更高的代码。因为运行在Server上的程序通常都会持续很久。
- Tiered编译的原理:
1)JVM启动之初使用Client版JIT编译器。
2)当HotSpot形成之后使用Server版JIT编译器再次编译。
- 在Java 8中,默认使用Tiered编译方式。
不过在Java7版本之后,一旦开发人员在程序中显式指定命令“-server”时,缺省将会开启分层编译(Tiered Compilation)策略,由client编译器和server编译器相互协作共同来执行编译任务。不过在早期版本中,开发人员则只能够通过命令“-XX:+TieredCompilation”手动开启分层编译策略。
1)-Xint:完全采用解释器模式执行程序;
2)-Xcomp:完全采用即时编译器模式执行程序;
3)-Xmixed:采用解释器+即时编译器的混合模式共同执行程序。
总结
- 当程序的启动速度越快越好时,使用Client版的JIT编译器更好。
- 就启动速度而言,Tiered编译方式的性能和只使用Client的方式十分接近,因为Tiered编译本质上也会在启动是使用Client JIT编译器。