jvm调优的学习

面试中经常被问到,怎么调优jvm,于是查了很多资料学习了一下,做一下总结,

1、jvm调优主要是针对垃圾回收,先要熟悉jvm内存模型,主要有堆内存,栈内存,堆内存是java对象new之后存放的区域,栈内存是java方法存放临时变量的区域,方法执行完栈内存会自动释放,垃圾回收需要清理的是堆内存

  a、堆内存中又分为新生代(年轻代),和老年代,默认新生代和老年代内存比例是1:2

  b、新生代的对象垃圾回收叫做Minor GC,如果新生代内存不够创建新对象了,会进行一次Minor GC,Minor GC的间隔时间一般比较短,10几秒-几分钟不等算正常,每次回收的时间50ms以下算正常,一般新生代的对象每次Minor GC后年龄会+1,默认到15岁就会进入老年代,当然可以通过jvm参数调整这个值

  c、老年代垃圾回收叫做full GC,如果老年代内存达到阈值,会进行一次full GC,full GC的间隔时间比较长,少则几小时,多则几天,每次回收的时间比minor GC长,1s以下算正常,如果超过5s以上,则考虑优化

2、jvm需要调优的情况

  a、首先使用jvm 工具jinfo -gc ${pid} 查看进程的gc情况,YGC就表示Minor GC次数,YGCT表示Minor GC的总时间(单位秒),FGC表示full GC的次数,FGCT表示full GC的总时间(单位秒),YGCT/YGC和FGCT/FGC可以计算平均时间

  b、如果Minor GC平均间隔较短,一般情况的参考值,平均每次gc时间大于50ms-200ms,cpu资源都花在gc上了。

  c、如果full GC的平均间隔时间较短,一般情况的参考值,平均每次gc时间大于1-10s,暂停时间教长,影响了用户体验

  d、jvm的常用vm flags有,-xms256m相当于-XX:InitialHeapSize=256m,表示启动初始堆内存,spring boot启动不指定时,默认是系统最大内存的1/64

              -xmx1g相当于-XX:MaxHeapSize=1g,表示虚拟机的最大堆内存,spring boot启动不指定时,默认是系统最大内存的1/4

  e、查看堆中类的构成,分析程序代码是否有可以优化的空间,要 避免 短命大对象(大对象在新生代创建时内存不够,就会直接进入老年代,存活时间又短,就会触发频繁gc),使用jvm工具jmap -dump:live,format=b,file=data.hprof  ${pid} 可以导出堆快照,然后再使用其他工具分析

        f、调优目标增大吞吐量(吞吐量= (程序运行总时间-垃圾回收时间)/程序运行总时间),减少停顿时间(减少平均响应时间)

3、调优策略

  a、可以设置-xms,-xmx堆内存的大小,一般xms与xms的比例可以设置为1:1,设置为1:1是为了固定堆内存,防止堆内存总体变大、变小,消耗资源

    -xms (--XX:InitialHeapSize)  ,

    -xmx (-XX:MaxHeapSize)

  b、可以设置新生代与老年代的比例,默认的比例是1:2,通过-XX:NewRatio=1:2设置

    -XX:NewRatio

  c、可以设置新生代中的Eden与Survivor的比值,默认值是-XX:SurvivorRatio=8,即比值是8:1,Survivor有2个且一样大

    -XX:SurvivorRatio

  d、可以设置垃圾收集器, (详细请看后面大佬的地址)

    新生代收集器:

      Serial
      ParNew
      Parallel Scavenge  (jdk7、jdk8 默认使用 Parallel Scavenge)
    老年代收集器:

      Serial Old
      CMS
      Parallel Old    (jdk7、jdk8 默认使用该收集器作为老年代收集器)
    堆内存垃圾收集器:G1    (G1 收集器是 jdk1.7 才正式引用的商用收集器,现在已经成为 jdk9 默认的收集器)

    使用配置

    -XX:+UseSerialGC:在新生代和老年代使用串行收集器
    -XX:+UseParNewGC:在新生代使用并行收集器
    -XX:+UseParallelGC :新生代使用并行回收收集器,更加关注吞吐量
    -XX:+UseParallelOldGC:老年代使用并行回收收集器
    -XX:ParallelGCThreads:设置用于垃圾回收的线程数
    -XX:+UseConcMarkSweepGC:新生代使用并行收集器,老年代使用CMS+串行收集器
    -XX:ParallelCMSThreads:设定CMS的线程数量
    -XX:+UseG1GC:启用G1垃圾回收器

4、调优步骤

  a、首先,准备一个测试环境,用jmeter模拟并发,用jvisualvm监控变化

  b、首先设置为生产环境的一样的vm参数,启动参数可以通过jinfo ${pid}查看到,启动程序,用jmeter模拟并发,计算出请求平均耗时

  c、然后,根据上面第三部分的优化策略调整vm参数

  d、然后用jmeter模拟并发,查看请求平均耗时

  e、不断反复尝试c、d步骤,找到最优的配置

参考大佬的博客地址,

https://blog.csdn.net/weixin_39639119/article/details/89005809

https://www.cnblogs.com/chenpt/p/9803298.html

原文地址:https://www.cnblogs.com/xiongjinpeng/p/12752097.html