jvm调优

开篇说明

本篇文章是初始级别熟悉jvm调优,主要通过解决cpu飙高,gc 频率过高
运行的多线程有死锁,本文用最原始的指令

解决cpu飙高

如果是无缘无故的cpu飙高,基本上是代码出问题,可能触发了什么地方
如何找到这块代码呢
主要是以下几个步骤

然后windows可以使用jvisualvm工具,linux使用Arthas

  1. 首先使用jps查找到jvm的进程id
  2. 可以将进程的信息保存下来,通过jstack 9272 > C:\test\cdf.log,命令的作用是将PID为9272的进程信息保存在本地C:\test\cdf.log文件中。
  3. 根据进程查找线程,也有两种方法。linux使用的是top命令
  4. 使用命令top -p ,显示你的java进程的内存情况,pid是你的java进程号,比如9272
  5. 按H,获取每个线程的内存情况
  6. 找到内存和cpu占用最高的线程tid
  7. 转为十六进制得到 0x4cd0,此为线程id的十六进制表示
  8. 执行 jstack 19663|grep -A 10 4cd0,得到线程堆栈信息中 4cd0 这个线程所在行的后面10行,从堆栈中可以发现导致cpu飙高的调用方法
  9. 查看对应的堆栈信息找出可能存在问题的代码

windows流程一样,但是top命令变为使用window自带命令pslist

首先确认系统是否安装了pslist命令程序,如果命令不识别即没有安装,则上微软官方网址http://technet.microsoft.com/en-us/sysinternals/bb896682.aspx下载,下载完将其解压到C:\Windows\System32路径下即可使用。

在cmd命令窗口中执行命令:pslist -dmx 9272,该命令的作用是罗列属于9272进程的线程信息

gc 频率过高

想要排查gc频率过高首先得了解jvm的一些基本参数

-Xms3072M JVM初始分配的内存由-Xms指定,默认是物理内存的1/64
-Xmx3072M JVM最大分配的内存由-Xmx指定,默认是物理内存的1/4

默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制;空余堆内存大于70%时,JVM会减少堆直到 -Xms的最小限制。
因此服务器一般设置-Xms、-Xmx相等以避免在每次GC 后调整堆的大小。对象的堆内存由称为垃圾回收器的自动内存管理系统回收。

-Xmn2048M 设置年轻代大小为2G。
-Xss1M 设置栈内存的大小,设置的栈的大小决定了函数调用的最大深度
-XX:MetaspaceSize=256M
-XX:MaxMetaspaceSize=256M
DK8及以后:可以使用-XX:MetaspaceSize和-XX:MaxMetaspaceSize设置元空间初始大小以及最大可分配大小。
-XX:SurvivorRatio=8
Eden占比80%,剩下两个s0,s1占10%

gc频率过高可能

1.有大对象直接进入老年代,或者有大对象进入年轻代
2.元空间不够
3.老年代空间分配担保机制
年轻代每次minor gc之前JVM都会计算下老年代剩余可用空间
如果这个可用空间小于年轻代里现有的所有对象大小之和(包括垃圾对象)

就会看一个“-XX:-HandlePromotionFailure”(jdk1.8默认就设置了)的参数是否设置了
如果有这个参数,就会看看老年代的可用内存大小,是否大于之前每一次minor gc后进入老年代的对象的平均大小。
如果上一步结果是小于或者之前说的参数没有设置,那么就会触发一次Full gc,对老年代和年轻代一起回收一次垃圾,如果回收完还是没有足够空间存放新的对象就会发生"OOM"
当然,如果minor gc之后剩余存活的需要挪动到老年代的对象大小还是大于老年代可用空间,那么也会触发full gc,full gc完之后如果还是没有空间放minor gc之后的存活对象,则也会发生“OOM”
在这里插入图片描述

查看gc日志

对于java应用我们可以通过一些配置把程序运行过程中的gc日志全部打印出来,然后分析gc日志得到关键性指标,分析GC原因,调优JVM参数。
开启gc日志打印后
在这里插入图片描述
我们可以看到图中第一行红框,是项目的配置参数。这里不仅配置了打印GC日志,还有相关的VM内存参数。
第二行红框中的是在这个GC时间点发生GC之后相关GC情况。
1、对于2.909: 这是从jvm启动开始计算到这次GC经过的时间,前面还有具体的发生时间日期。
2、Full GC(Metadata GC Threshold)指这是一次full gc,括号里是gc的原因, PSYoungGen是年轻代的GC,ParOldGen是老年代的GC,Metaspace是元空间的GC
3、 6160K->0K(141824K),这三个数字分别对应GC之前占用年轻代的大小,GC之后年轻代占用,以及整个年轻代的大小。
4、112K->6056K(95744K),这三个数字分别对应GC之前占用老年代的大小,GC之后老年代占用,以及整个老年代的大小。
5、6272K->6056K(237568K),这三个数字分别对应GC之前占用堆内存的大小,GC之后堆内存占用,以及整个堆内存的大小。
6、20516K->20516K(1069056K),这三个数字分别对应GC之前占用元空间内存的大小,GC之后元空间内存占用,以及整个元空间内存的大小。
7、0.0209707是该时间点GC总耗费时间。

从日志可以发现几次fullgc都是由于元空间不够导致的,所以我们可以将元空间调大点

总结

每个问题都是不会一模一样,写下这篇文章是为了出现问题时,提供一个思路,公式,望自己以后能熟练jvm。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值