Java 虚拟机入门教程之五 JVM 性能优化
大纲
- Java 虚拟机入门教程之一 JVM 内存结构
- Java 虚拟机入门教程之二 JVM 垃圾收集
- Java 虚拟机入门教程之三 JVM 参数调优
- Java 虚拟机入门教程之四 JVM 四种引用
- Java 虚拟机入门教程之五 JVM 性能优化
- Java 虚拟机入门教程之六 JVM 类加载机制
前言
JVM 调优,调的是稳定,并不能让性能得到大幅提升。服务稳定的重要性就不用多说了,保证服务的稳定,GC 永远会是 JAVA 程序员需要考虑的不稳定因素之一。复杂和高并发下的服务,必须保证每次 GC 不会出现性能下降,各种性能指标不会出现波动,GC 回收规律而且干净,找到合适的 JVM 设置。比如,FULL GC 最会影响性能,根据代码问题,避免 FULL GC 频率。可以适当调大年轻代的容量,让大对象可以在年轻代触发 YONG GC,调整大对象在年轻代的回收频次,尽可能保证大对象在年轻代回收,减小老年代缩短回收时间。
性能优化工具的介绍
工具 | 说明 |
---|---|
jstack | 查看 JVM 线程运行状态,是否有死锁现象等信息 |
jinfo | 可以输出并修改运行时的 Java 进程的 opts |
jps | 与 Unix 上的 ps 命令类似,用来显示本地的 Java 进程,可以查看本地运行着几个 Java 程序,并显示它们的进程号 |
jstat | 一个极强的监视 VM 内存工具。可以用来监视 VM 内存内的各种堆和非堆的大小及其内存使用量 |
jmap | 打印出某个 Java 进程(使用 pid )内存内的所有 对象 的情况(如:产生哪些对象及其数量) |
性能优化工具的使用
在使用下述工具前,建议先用 jps
命令获取当前的每个 JVM 进程号,然后再选择要查看的 JVM 进程。
jstat 使用
jstat
是 JDK 自带的工具,特别强大,参数有众多的可选项,可详细地查看堆内各个部分的使用量,以及类加载的数量。使用时,需加上应用的进程 id
和所选参数。
命令 | 说明 |
---|---|
jstat -class pid | 显示加载 Class 的数量,及所占空间等信息 |
jstat -compiler pid | 显示 VM 实时编译的数量等信息 |
jstat -gc pid | 显示 GC 的信息,查看 GC 的次数与时间 |
jstat -gccapacity pid | 堆内存统计,包括堆内存的使用和占用大小 |
jstat -gcnew pid | 新生代垃圾回收统计 |
jstat -gcnewcapacity pid | 新生代内存统计 |
jstat -gcold pid | 老年代垃圾回收统计 |
jstat -gcutil pid | 堆内存(包括新生代、老年代)的垃圾回收统计 |
除了以上 pid
参数外,还可以同时加上两个数字,示例如下:
jstat -gcutil pid 1000 100
: 每 1000 毫秒统计一次 GC 情况,一共统计 100 次jstat -printcompilation pid 250 6
: 表示每 250 毫秒打印一次,一共打印 6 次,还可以加上-h3
参数使每三行显示一次标题
jinfo 使用
jinfo
是 JDK 自带的工具,可以用来查看正在运行的 Java 应用程序的扩展参数,包括 Java System 属性和 JVM 命令行参数;也可以动态地修改正在运行的 JVM 一些参数。当系统崩溃时,jinfo
可以从 core 文件里面知道崩溃的 Java 应用程序的配置信息。
命令 | 说明 |
---|---|
jinfo pid | 输出当前 JVM 进程的全部参数和系统属性 |
jinfo -flag name pid | 查看指定的 JVM 参数的值,打印结果: - 无此参数,`+ 有此参数 |
jinfo -flag [+/-]name pid | 开启或者关闭对应名称的参数(无需重启虚拟机) |
jinfo -flag name=value pid | 修改指定参数的值 |
jinfo -flags pid | 输出全部的参数 |
jinfo -sysprops pid | 输出当前 JVM 进行的全部的系统属性 |
jmap 使用
jmap
是 JDK 自带的工具,可以生成堆内存的 Dump 文件,也可以查看堆内对象分析内存信息等,如果不使用这个命令,还可以使用 -XX:+HeapDumpOnOutOfMemoryError
参数来让虚拟机在出现 OOM 的时候自动生成 Dump 文件。
命令 | 说明 |
---|---|
jmap -dump:live,format=b,file=product.dump pid | Dump 堆内存到指定的文件,format 指定输出格式,live 指明是活着的对象,file 指定文件名。Eclipse 可以直接打开这个文件 |
jmap -heap pid | 打印堆内存的概要信息,包括 GC 使用的算法、堆内存的配置和使用情况,可以用此来判断目前内存的使用情况以及垃圾回收情况 |
jmap -finalizerinfo pid | 打印等待回收的对象信息 |
jmap -histo:live pid | 打印堆的对象统计,包括对象数、内存大小等。特别注意,这个命令执行,JVM 会先触发一次 GC,然后再统计信息 |
jmap -clstats pid | 打印 Java 类加载器的智能统计信息,对于每个类加载器而言,它的名称、活跃度、地址、父类加载器、加载的类的数量和大小都会被打印。此外,包含的字符串数量和大小也会被打印 |
-F
参数表示强制模式。如果指定的 pid
没有响应,请使用 jmap -dump
或 jmap -histo
选项。此模式下,不支持 live
子选项。使用示例:jmap -F -histo pid
。
jstack 使用
jstack
是 JDK 自带的线程堆栈分析工具,使用该命令可以查看或导出 Java 应用程序中的线程堆栈信息。
命令 | 说明 |
---|---|
jstack pid | 输出当前 JVM 进程的线程堆栈信息 |