JVM调优

行性能监控和故障处理指令

  • 操作系统工具
    • top:显示系统整体资源使用情况
    • vmstat:监控内存和CPU
    • iostat:监控IO使用
    • netstat:监控网络使用
  • JDK性能监控工具
    • jps:虚拟机进程查看
    • jstat:虚拟机运行时信息查看
    • jinfo:虚拟机配置查看
    • jmap:内存映像(导出)
    • jhat:堆转储快照分析
    • jstack:Java堆栈跟踪
    • jcmd:实现上面除了jstat外所有命令的功能

可视化的性能监控和故障处理工具

JDK自带的性能监控工具

JConsole

VisualVM等

还有一些第三方的工具

MAT

JProfiler 等

常见参数配置

堆配置:

  • -Xms:初始堆大小
  • -Xms:最大堆大小
  • -XX:NewSize=n:设置年轻代大小
  • -XX:NewRatio=n:设置年轻代和年老代的比值。如:为3表示年轻代和年老代比值为1:3,年轻代占整个年轻代年老代和的1/4
  • -XX:SurvivorRatio=n:年轻代中Eden区与两个Survivor区的比值。注意Survivor区有两个。如3表示Eden: 3 Survivor:2,一个Survivor区占整个年轻代的1/5
  • -XX:MaxPermSize=n:设置持久代大小

收集器设置:

  • -XX:+UseSerialGC:设置串行收集器
  • -XX:+UseParallelGC:设置并行收集器
  • -XX:+UseConcMarkSweepGC:设置并发收集器
  • -XX:+UseParalledlOldGC:设置并行年老代收集器

并行收集器设置

  • -XX:ParallelGCThreads=n:设置并行收集器收集时使用的CPU数。并行收集线程数
  • -XX:MaxGCPauseMillis=n:设置并行收集最大的暂停时间(如果到这个时间了,垃圾回收器依然没有回收完,也会停止回收)
  • -XX:GCTimeRatio=n:设置垃圾回收时间占程序运行时间的百分比。公式为:1/(1+n)
  • -XX:+CMSIncrementalMode:设置为增量模式。适用于单CPU情况
  • -XX:ParallelGCThreads=n:设置并发收集器年轻代手机方式为并行收集时,使用的CPU数。并行收集线程数

打印GC回收的过程日志信息

  • -XX:+PrintGC
  • -XX:+PrintGCDetails
  • -XX:+PrintGCTimeStamps
  • -Xloggc:filename

JVM调优思路

  • 判断是否需要调优

如果各项参数设置合理,系统没有超时日志出现,GC 频率不高,GC 耗时不高,那么没有必要进行 GC 优化,如果 GC 时间超过 1-3 秒,或者频繁 GC,则必须优化

  • 常规调优步骤

第一步:分析系统运行情况

a、实时监控

可以通过LINUX指令或者JDK指令查看程序运行情况(例如:查看那个进程占用cup比较高)

b、事后分析

所谓事后分析,指已经出现问题,通过GC日志分析(GCEasy等来分析GC情况,了解GC的频率、时间、内存占用等情况)或者堆存储快照分析

第二步:确定jvm调优量化目标

根据分析系统运行情况,明确内存使用率,停顿时间,回收频率等

第三步:确定调优参数

通过压测,调优内存,延迟等指标,对比调优前后差异。重复多次以上步骤。找到合适的参数

CPU飙高的排查思路

cpu飙高原因分析:肯定是存在程序长期占用CPU资源不释放。

  • 排查步骤

1、所以先需要找出那个进程占用CPU高。

top 列出系统各个进程的资源占用情况。

2、然后根据找到对应进行里哪个线程占用CPU高。

top -Hp 进程ID 列出对应进程里面的线程占用资源情况

3、找到对应线程ID后,再打印出对应线程的堆栈信息

jstack PID 打印出进程的所有线程信息,从打印出来的线程信息中找到上一步转换为16进制的线程ID对应的线程信息。

4、最后根据线程的堆栈信息定位到具体业务方法,从代码逻辑中找到问题所在。

查看是否有线程长时间的watting 或blocked,如果线程长期处于watting状态下, 关注watting on xxxxxx,说明线程在等待这把锁,然后根据锁的地址找到持有锁的线程。

内存飙高排查思路

分析: 内存飚高如果是发生在java进程上,一般是因为创建了大量对象所导致,持续飚高说明垃圾回收跟不上对象创建的速度,或者内存泄露导致对象无法回收。

1、先观察垃圾回收的情况

  • jstat -gc PID 1000 查看GC次数,时间等信息,每隔一秒打印一次。
  • jmap -histo PID | head -20 查看堆内存占用空间最大的前20个对象类型,可初步查看是哪个对象占用了内存。

如果每次GC次数频繁,而且每次回收的内存空间也正常,那说明是因为对象创建速度快导致内存一直占用很高;如果每次回收的内存非常少,那么很可能是因为内存泄露导致内存一直无法被回收。

2、导出堆内存文件快照

  • jmap -dump:live,format=b,file=/home/myheapdump.hprof PID dump堆内存信息到文件。

3、使用visualVM对dump文件进行离线分析,找到占用内存高的对象,再找到创建该对象的业务代码位置,从代码和业务场景中定位具体问题。

判断是否内存泄露

在jstat命令行工具中可以根据如下的思路来判断是否可能出现了内存泄露,具体思路如下:

  • 运行中的Java程序,运行jstat命令行工具获取JVM运行的数据,重点关注OU值的数据(OU:老年代目前已使用空间)

  • 重复如上的操作,如果OU的值呈上升的趋势,说明Java程序的老年代内存已使用量在不断上涨,那么也就意味着无法回收的对象在不断的增加,很有可能存在内存泄露。

  • 5
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值