JVM调优说明

是不是Java项目都需要进行JVM调优呢?其实不太算,JVM调优应该是我们想要对Java应用做的最后一项优化工作,我们调优主要是为了减少垃圾回收的时间或性能,一般是吞吐量暂停时间

  • 吞吐量:吞吐量是指应用程序线程用时占程序总用时的比例。像:CMS + ParNew。一般用户交互多。
  • 暂停时间:指一个时间段内应用程序线程让与 GC 线程执行而完全暂停。像:Parallel Old + Parallel Scavenge。用户交互少,专注于后台计算

一般这两个指标是互逆的,增加一个另外一个会减少。

一般情况下系统的默认配置都不会有太大的问题,如果存在问题,很可能是我们的程序写的比较糟糕。JVM的GC是为了清理不必要的对象,首先我们第一步要做的可以是减少对象创建的数量。

  • 如使用StringBuilderStringBuffer代替String相加
  • 控制日志的量。打印日志的时候使用占位符 {},而不是使用+

不过有的时候我们还是没办法控制对象创建的数量,比如说解析XML,解析JSON的时候都需要很多的临时内存,在程序没什么大问题的时候,如果JVM调参确实改善性能的话,还是可以做的。可以将吞吐量与延迟时间换成如下描述。

  • 减少复制到老年代的对象数量
    • 不是让对象只停留在新生代
  • 减少Full GC的执行时间
    • 如果老年代设置的太小,可能导致OutOfMemoryError
    • 如果老年代设置的太大,可能增加Full GC的时间

不同应用,不同对待

应用的类型,创建对象的方式都不同,不要调整好一个应用的参数后,拿出来用在其他的应用上。想要做JVM调优,最好是针对一个应用,采用不同的参数来对比性能的变化。

一些常用参数:

  • -Xms 启动JVM的时候堆大小

  • -Xmx 堆的最大大小

  • -Xmn 年轻代的堆大小

  • -XX:+UseSerialGC 使用串行垃圾回收器,新生代和老年代都使用

  • -XX:+UseParallelGC 使用并行垃圾收集器,代表新生代使用Parallel Scavenge收集器,老年代使用串行收器

  • -XX:ParallelGCThreads=value 并行垃圾收集器的线程数量

  • -XX:+UseParallelOldGC Parallel Old + Parallel Scavenge收集器

  • -XX:+UseConcMarkSweepGC 使用CMS垃圾收集器

  • -XX:+UseParNewGC 使用并行新生代垃圾收集器

  • -XX:+CMSParallelRemarkEnabled 是否开启并发标记

  • -XX:CMSInitiatingOccupancyFraction=value 老年代空间的使用率来触发GC

  • -XX:+UseCMSInitiatingOccupancyOnly 当该标志被开启时,JVM通过CMSInitiatingOccupancyFraction值进行每一次CMS收集,而不仅仅是第一次。

  • -XX:+UnlockExperimentalVMOptions 采用JVM的实验性特点

  • -XX:+UseG1GC 采用G1垃圾回收器

  • -XX:NewRatio:年轻代(包括Eden和两个Survivor区)与年老代的比值(除去持久代)
  • -XX:SurvivorRatio:Eden区与Survivor区的大小比值
  • -XX:+DisableExplicitGC 关闭System.gc()
  • -XX:MaxTenuringThread 对象在Suvivor区域中的年龄到达多少进入Old Gen
  • -XX:PretenureSizeThreshold 另大于这个设置值的对象直接在老年代分配,避免Eden区和Suvivor区域之间大量的内存分配

调优步骤

1 监控JVM的状况,可以使用阿里新开源的arthas,或者jconsole等工具查看运行状态

2 判断是否需要调优,如果GC时间在0.1~0.3s的时候,我们是不需要花费太多精力在JVM调优上的。如果GC执行时间在1s钟以上,那还是有必要进行JVM调优的,GC时间越长,对应用影响越大。

3 选取垃圾回收器的类型,针对不同的应用类型选取特点垃圾回收器。然后设置合适的内存大小

4 分析调整参数后的结果,直到达到满意的效果。至少要观察24小时的日志情况

-XX:+PrintGC -XX:+PrintGCCause -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:/Users/aihe/idea/idea_gc.txt -XX:+DisableExplicitGC  -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home/issue_error

最后

简单对JVM调优做了说明

参考:

  • Java的垃圾回收机制-垃圾收集算法(一)
  • How to Tune Java Garbage Collection

你可能感兴趣的:(JVM调优说明)