【JVM】3.调优

判断是否需要调优

如果各项参数设置合理,系统没有超时日志或异常信息的出现,GC频率不高,GC耗时不高,那么没有必要进行GC优化,如果GC时间超过1~3s,或者频繁GC,则必须优化,遇到下面的情况,就需要考虑进行jvm调优:

  • 系统吞吐量与相应性能不高或下降
  • Heap内存(老年代)持续上涨达到设置的最大内存值
  • FullGC次数频繁
  • GC停顿时间过长
  • 应用出现OutOfMemory等内存异常
  • 应用中有使用本地缓存且占用大量内存空间

调优目标

调优的最终目的是为了应用程序使用最小的硬件来承载更大的吞吐量或低延时,jvm调优主要针对垃圾收集器的收集性能优化,减少gc的频率和full gc的次数,使运行在虚拟机上的应用能使用更少的内存,提高吞吐量,降低延迟

下面举一些目标例子:

  • 堆内存使用率<=70%
  • 老年代内存使用率<=70%
  • avgpause<=1s
  • full gc 次数为0或平均暂停间隔时间>=24h

调优顺序

程序所需内存->时间延迟->吞吐量

调优工具

1. jps

JVM Process Status Tool,可以查看java进程

1.1 语法
jps:列出Java程序进程ID和Main函数名称
jps -q:只输出进程ID
jps -m:输出传递给Java进程(主函数)的参数
jps -l:输出主函数的完整路径
jps -v:显示传递给Java虚拟的参数

2. jstat

JVM Statistics Monitoring Tool jstat 可以查看java程序运行时相关信息

2.1 语法
jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]

option可通过jstat -options获取

options可选值

-class:显示ClassLoader的相关信息
-compiler:显示JIT编译的相关信息
-gc:显示与GC相关信息
-gccapacity:显示各个代的容量和使用情况
-gccause:显示垃圾收集相关信息(同-gcutil),同时显示最后一次或当前正在发生的垃圾收集的诱发原因
-gcnew:显示新生代信息
-gcnewcapacity:显示新生代大小和使用情况
-gcold:显示老年代信息
-gcoldcapacity:显示老年代大小
-gcpermcapacity:显示永久代大小
-gcutil:显示垃圾收集信息
-printcompilation:输出JIT编译的方法信息
-t:在输出信息前加上一个Timestamp列,显示程序的运行时间
-h:可以在周期性数据输出后,输出多少行数据后,跟着一个表头信息
interval:用于指定输出统计数据的周期,单位为毫秒
count:用于指定一个输出多少次数据
2.2 示例

查询进程ID为4145的java程序的GC信息,采样时间1000ms,采样数量为2

jstat -gc 4145 1000 2
 S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT   
125440.0 127488.0  0.0   2192.1 768512.0 294475.5  494080.0   185113.9  96216.0 91689.8 11520.0 10547.7     23    3.431   4      2.970    6.401
125440.0 127488.0  0.0   2192.1 768512.0 294475.5  494080.0   185113.9  96216.0 91689.8 11520.0 10547.7     23    3.431   4      2.970    6.401
2.3 注解
S0C:年轻代中第一个survivor(幸存区)的容量 (字节)
S1C:年轻代中第二个survivor(幸存区)的容量 (字节)
S0U:年轻代中第一个survivor(幸存区)目前已使用空间 (字节)
S1U:年轻代中第二个survivor(幸存区)目前已使用空间 (字节)
EC :年轻代中Eden(伊甸园)的容量 (字节)
EU :年轻代中Eden(伊甸园)前已使空间 (字节)
OC :Old代的容量 (字节)
OU :Old代目前已使用空间 (字节)
MC:metaspace(元空间)的容量 (字节)
MU:metaspace(元空间)目前已使用空间 (字节)
CCSC:压缩类空间大小
CCSU:压缩类空间使用大小
YGC :从应用程序启动到采样时年轻代中gc次数
YGCT :从应用程序启动到采样时年轻代中gc所用时间(s)
FGC :从应用程序启动到采样时old代(全gc)gc次数
FGCT :从应用程序启动到采样时old代(全gc)gc所用时间(s)
GCT:从应用程序启动到采样时gc用的总时间(s)

3 jinfo

Java Configuration Info 可以用来查看正在运行的java程序的扩展参数,支持运行时修改部分参数

jinfo [option] <pid>
jinfo [option] <executable <core>
3.1 示例1:查询进行ID4145的最大堆值

flag name 可通过 jinfo -flags pid打印

jinfo -flag MaxHeapSize 4145
3.2 查询4145的所有参数
jinfo -flags 4145

4. jmap

Memory Map 可以查看堆内存的使用情况,一般集合jhat使用

4.1 用法
jmap [option] <pid>

option可选值

no option: 查看进程的内存映像信息,类似 Solaris pmap 命令
heap: 显示Java堆详细信息 
histo[:live]: 显示堆中对象的统计信息 
clstats:打印类加载器信息 
finalizerinfo: 显示在F-Queue队列等待Finalizer线程执行finalizer方法的对象 
dump:<dump-options>:生成堆转储快照 F:当-dump没有响应时,使用-dump或者-histo参数。在这个模式下,live子参数无效 
help:打印帮助信息 J<flag>:指定传递给运行jmap的JVM的参数
4.2 示例

打印java堆的详细信息

jmap -heap 4145

生成堆快照dump文件,线上慎用,会暂停应用

jmap -dump:format=b,file=heapdump.dump pid

5 jhat

Java Heap Analysis Tool, 解析Java堆转储文件并启动一个 web server,然后用浏览器来查看、浏览 dump 出来的 heap

5.1 语法
jhat [-stack <bool>] [-refs <bool>] [-port <port>] [-baseline <file>] [-debug <int>] [-version] [-h|-help] <file>
5.2 示例开启一个本地服务解析dump文件
jhat dump-flie-path

6 jstack

jstack命令通常配置top使用,通过top -H -p pid定位java进程和线程,再利用jstack -l pid 导出线程栈,一般需要多次dump,每次隔5s

6.1 语法
jstack [-l] <pid> 查看当前时间点,指定进程的dump堆栈信息
jstack -F [-m] [-l] <pid>
jstack [-m] [-l] <executable> <core>
jstack [-m] [-l] [server_id@]<remote server IP or hostname>

option可选值

-F 强制jstack。当进程挂起了,此时'jstack [-l] pid'是没有响应的,这时候可使用此参数来强制打印堆栈信息,一般情况不需要使用。
-m 打印java和native c/c++框架的所有栈信息。可以打印JVM的堆栈,以及Native的栈帧,一般应用排查不需要使用。
-l 长列表。打印关于锁的附加信息。例如属于java.util.concurrent的ownable synchronizers列表,会使得JVM停顿得久得多(可能会差很多倍,如普通的jstack可能毫秒和次GC没区别,加了-l 就是近一秒的时间),-l 建议不要用。一般情况不需要使用。-h or -hel 打印帮助信息

7 hprof

Heap/CPU Profiling Tool 能够展现CPU使用率,统计堆内存使用情况

7.1 语法
java -agentlib:hprof[=options] ToBeProfiledClassjava -Xrunprof[:options] ToBeProfiledClassjavac -J-agentlib:hprof[=options] ToBeProfiledClass

8 jconsole

Java Monitoring and Management Console,Java 5引入,一个内置 Java 性能分析器,可以从命令行或在 GUI shell 中运行。您可以轻松地使用 JConsole来监控 Java 应用程序性能和跟踪Java 中的代码

性能诊断工具

针对java应用,诊断工具主要分为两层:OS层面和java应用层面(包括代码诊断和GC诊断)

OS诊断

针对os我们需要关注:CPU、Memory、I/O

CPU

cpu需要关注平均负载(Load Average), CPU使用率,上下文切换次数(Context Switch)

  1. 通过top命令可以查看系统平均负载和cpu使用率
    在这里插入图片描述
    Load Avg的三个数字分别表示过去1分钟、5分钟、15分钟的机器负载,若数值小于0.7*cpu个数,则系统工作正常,若超过这个值,甚至达到cpu核数的四五倍,则系统的负载明显偏高
  2. 通过vmstat命令可以查看cpu的上下文切换次数
Memory

使用free -m命令查看内存使用情况
通过top命令查看进程使用的虚拟内存virt和物理内存res,根据公式virt=swap+res可以推算出具体应用使用的交换分区,使用交换分区过大会影响java的性能

I/O

I/O包括磁盘I/O和网络I/O,一般情况下磁盘更容易出现I/O瓶颈,通过iostat可以查看磁盘的读写情况,通过cpu的I/O wait查看磁盘I/O是否正常

Java应用诊断

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值