1. 选择JVM运行模式
a. Client模式:启动快,占用内存少,JIT编译器生成代码的速度也更快。
b. Server模式:提供了更复杂的生成代码优化功能,这个功能对服务器应用而言尤其重要。大多数Server模式的JIT的编译优化都要消耗额外的时间以收集更多的应用程序行为信息,为应用程序运行生成更优的代码。
c. Tiered Server模式:结合Client和Server运行模式的长处,即快速启动和高效的生成码。 -server -xx:+Tieredcompilation命令。可取代Client运行时。
2. 选择32位/46位的JVM
3. 垃圾回收器
a. Serial收集器 b. Throughtput 收集器 c. Mostly-Concurrent收集器 d. G1收集器
影响垃圾收集性能的三个属性:吞吐量、延迟、内存占用。其中任何一个属性的提高几乎都是以另一个或两个属性性能的损失作为代价的。
JVM垃圾收集调优的三个原则:
a. 每次MinorGC都尽可能多地收集垃圾对象。->减少Full GC的频率(Minor GC 最大化原则)
b. 处理吞吐量和延迟问题时,垃圾处理器能使用的内存越大,即Java堆内存越大,垃圾收集的效果越好,应用程序运行也越流畅。
c. 在三个性能属性(吞吐量、延迟、内存占用)中任意选择两个进行JVM垃圾收集器调优。我们称之为“GC调优的3选2原则”。
4. 命令行选项及GC日志
5. 确定内存占用
活跃数据大小:应用程序稳定运行时长期存活对象所占用的Java堆内存量。PS:应用程序运行于稳定态时,FullGC之后Java堆占用的空间大小。
a. 解决 out of mermory Errors
对于老年代引起的out of mermory Errors,增加-Xms和-Xmx值
对于永久代引起的out of mermory Errors,增加-xx:permsize和-xx:MaxPermSize
b. 计算活跃数据大小
应用程序运行于稳定态时,老年代占用Java堆大小;应用程序运行于稳定态时,永久代占用Java堆大小。
(如果不经常发生FullGC,可以人工触发)
c. 设置堆内存法则:
法则一:将Java堆的初始值-Xms和最大值-Xmx设置为年老代活跃数据大小的3~4倍
法则二:永久代的初始值-xx:PermSize及最大值-xx:MaxPermSize应该比永久代活跃数据大1~1.5倍
法则三:新生代空间应该为老年代空间活跃数据的1~1.5倍,老年代应该设置为活跃数据大小的2~3倍
空间 | 命令行选项 | 占用倍数 |
Java堆 | -Xms和-Xmx | 3~4倍FullGC后的老年代空间占用量 |
永久代 | -xx:PermSize和-xx:MaxPermSize | 1.2~1.5倍FullGC后的永久代空间占用量 |
新生代 | -Xmn | 1~1.5倍FullGC后的老年代空间占用量 |
老年代 | Java堆大小减新生代大小 | 2~3倍FullGC后的老年代空间占用量 |
如果调优无法满足,则需回顾或者修改应用程序的内存需求,调整应用程序,减少对象分配或者更重要的,减少对象保持可以减少活跃数据的大小。