何时进行JVM调优
遇到以下情况,就需要考虑进行JVM调优了:
- Heap内存(老年代)持续上涨达到设置的最大内存值;
- Full GC 次数频繁;
- GC 停顿时间过长(超过1秒);
- 应用出现OutOfMemory等内存异常;
- 应用中有使用本地缓存且占用大量内存空间;
- 系统吞吐量与响应性能不高或不降。
JVM调优的基本原则
JVM调优是一个手段,但并不一定所有问题都可以通过JVM进行调优解决;因此,在进行JVM调优时,我们 要遵循一些原则 :
- 大多数的Java应用不需要进行JVM优化;
- 大多数导致GC问题的原因是代码层面的问题导致的(代码层面);
- 上线之前,应先考虑将机器的JVM参数设置到最优;
- 减少创建对象的数量(代码层面);
- 减少使用全局变量和大对象(代码层面);
- 优先架构调优和代码调优,JVM优化是不得已的手段(代码、架构层面);
- 分析GC情况优化代码比优化JVM参数更好(代码层面)。
通过以上原则,我们发现, 其实最有效的优化手段是架构和代码层面的优化,而JVM优化则是最后不得已的手段,也可以说是对服务器配置的最后一次“压榨”。
JVM调优目标
调优的最终 目的都是为了令应用程序使用最小的硬件消耗来承载更大的吞吐。 JVM调优 主要是针对垃圾收集器的收集性能优化 ,令运行在虚拟机上的应用能够使用更少的内存以及延迟获取更大的吞吐量,总结以下:
- 延迟:GC低停顿和GC低频率;
- 低内存占用;
- 高吞吐量。
其中任何一个属性性能的提高,几乎都是以牺牲其他属性性能的损为代价的, 不可兼得 。具体根据在业务中的重要性确定。
常用的参数
-
-Xms和-Xmx:这两个参数用来设置JVM的初始堆大小和最大堆大小。-Xms设置初始堆大小,-Xmx设置最大堆大小。这两个参数一般需要根据应用程序的内存需求进行调整,以避免出现OutOfMemoryError错误。例如,可以设置为-Xms2G和-Xmx4G,表示初始堆大小为2GB,最大堆大小为4GB。
-
-Xmn:这个参数用来设置JVM的新生代的堆大小。新生代是JVM中的一个重要部分,用于存放新创建的对象。一般来说,新生代的大小应该根据应用程序的对象创建和销毁速度进行调整,以避免频繁的垃圾回收。例如,可以设置为-Xmn1G,表示新生代的堆大小为1GB。
-
-XX:PermSize和-XX:MaxPermSize:这两个参数用来设置JVM的永久代的大小。永久代是JVM中用来存放类的元数据和常量池等信息的区域。一般来说,永久代的大小应该根据应用程序的类的数量和复杂程度进行调整。例如,可以设置为-XX:PermSize256M和-XX:MaxPermSize512M,表示永久代的大小区间为256MB到512MB。
-
-XX:SurvivorRatio:这个参数用来设置新生代中eden区与survivor区的大小比例。例如,可以设置为-XX:SurvivorRatio=8,表示eden区的大小是survivor区大小的8倍。
-
-XX:+UseParallelGC和-XX:+UseConcMarkSweepGC:这两个参数用来选择JVM使用的垃圾回收器。-XX:+UseParallelGC表示使用并发垃圾回收器,-XX:+UseConcMarkSweepGC表示使用CMS垃圾回收器。并发垃圾回收器适合多核的情况下,可以减少垃圾回收的停顿时间;CMS垃圾回收器适合对响应时间有较高要求的应用程序。
-
-XX:+UseCompressedOops:这个参数用来启用压缩指针。压缩指针可以减少内存的使用,提高内存的效率,特别是在64位的JVM上。
-
-XX:MaxTenuringThreshold:这个参数用来设置对象经过多少次垃圾回收后进入老年代。一般来说,如果应用程序中有很多对象长时间存活,可以适当增加这个值,以减少对象被频繁转移到老年代的次数。例如,可以设置为-XX:MaxTenuringThreshold=20。
-
-XX:ParallelGCThreads:这个参数用来设置垃圾回收器的线程数。一般来说,如果应用程序有多个CPU核心,可以增加垃圾回收器的线程数,以提高垃圾回收的效率。例如,可以设置为-XX:ParallelGCThreads=8。