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