概述

性能诊断是软件工程师在日常工作中需要经常面对和解决的问题,在用户体验至上的今天,解决好应用的性能问题能带来非常大的收益。

Java作为最流行的编程语言之一,其应用性能诊断一直受到业界广泛关注。可能造成Java应用出现性能问题的因素非常多,例如线程控制、磁盘读写、数据库访问、网络I/O、垃圾收集等。想要定位这些问题,一款优秀的性能诊断工具必不可少。

体会1:使用数据说明问题,使用知识分析问题,使用工具处理问题。

体会2:无监控、不调优。

jps:查看正在运行的Java进程

jps(Java Process Status),显示指定系统内所有HotSpot虚拟机进程(查看虚拟机进程信息),可用于查询正在运行的虚拟机进程。

说明:对于本地虚拟机进程来说,进程的本地虚拟机ID与操作系统的进程ID是一致的,是唯一的。

官方文档:https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jps.html

基本语法

 jps [options] [hostid]

参数说明

options

  • -q:仅仅显示LVMID(local virtual machine id),即本地虚拟机唯一id,不显示主类的名称等。

  • -l:输出应用程序主类的全类名或如果进行执行的是jar包,则输出jar完整路径

  • -m:输出虚拟机进程启动时传递给主类main()的参数

  • -v:列出虚拟机进程启动时的JVM参数,比如-Xms100m -Xmx100m是启动程序指定的JVM参数

  • -V:通过标志文件(.hotspotrc文件或-XX:Flags=< *filename* >参数指定的文件)输出传递给 JVM 的参数

  • 以上参数可以综合使用

hostid

  • RMI注册表注册的主机名。如果想要远程监控主机上的Java程序,需要安装jstatd。对于具有更严格的安全实践的网络场所而言,可能使用一个自定义的策略文件来显示堆特定的可信主机或网络的访问,尽管这种技术容易受到IP地址欺诈攻击。如果安全问题无法使用一个定制的策略文件来处理,那么最安全的操作是不允许jstatd服务器,而是在本地是使用jstat和jps工具。

补充说明:如果某Java进程关闭了默认开启的UsePerData参数(即使用参数-XX:-UsePerData),那么jps命令(以及下面介绍的jstat)将无法探知该Java进程。

jstat:查看jvm统计信息

jstat(JVM Statistics Monitoring Tool):用于监视虚拟机各种运行状态信息的命令行工具。它可以显示本地或者远程虚拟机进程中的类装载、内存、垃圾收集、JIT编译等运行数据。

在没有GUI图形界面,只提供了纯文本控制台环境的服务器上,它将是运行期定位虚拟机性能问题的首选工具。常用于检测垃圾回收问题以及内存泄漏问题。

官方文档:https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jstat.html

基本语法

 jstat -<options> [-t] [-h<lines>] <vmid> [<interval> [<count>]]

参数说明

  • options

    • 类装载相关的

      • -class:显示ClassLoader的相关信息:类的装载、卸载数量、总空间、类装载所消耗的时间等

    • 垃圾回收相关的

      • -gc:显示与GC相关的堆信息。包括Eden区、两个Survivor区、老年代、永久代等的容量、已用空间、GC时间合计等信息

      • -gccapacity:显示内容与-gc基本相同,但输出主要关注Java堆各个区域使用到的最大、最小空间

      • -gcutil:显示内容与-gc基本相同,但输出主要关注已使用空间占总空间的百分比

      • -gccause:与-gcutil功能一样,但是会额外输出导致最后一次或当前正在发生的GC产生的原因

      • -gcnew:显示新生代GC状况

      • -gcnewcapacity:显示内容与-gcnew基本相同,输出主要关注使用到的最大、最小空间

      • -geold:显示老年代GC状况

    • JIT相关的

      • -compiler:显示JIT编译器编译过的方法、耗时等信息

      • -printcompilation:输出已经被JIT编译的方法

  • -t:可以在输出信息前加上一个Timestamp列,显示程序的运行时间,单位:秒

  • -h:可以在周期性数据输出时,输出多少行数据后输出一个表头信息(-h3表示每隔3次输出打印一次表头,以此类推)

  • vmid:虚拟机线程id

  • interval:用于指定输出统计数据的周期,单位为毫秒,即,查询间隔

  • count:用于指定查询的总次数

jinfo:实时查看和修改JVM配置参数

jinfo(Configuration Info for Java),查看虚拟机配置参数信息,也可用于调整虚拟机的配置参数。

在很多情况下,Java应用程序不会指定所有的Java虚拟机参数,而此时,开发人员可能不知道某一个具体的Java虚拟机参数的默认值。在这种情况下,可能需要通过查看文档获取某个参数的默认值。这个查找过程可能是非常艰难的。但有了jinfo工具,开发人员可以很方便地找到Java虚拟机参数的当前值。

官方文档:https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jinfo.html

基本语法

 jinfo [options] pid

参数说明

options

选项

选项说明

/

输出全部的参数和系统属性

-flag name

输出对应名称的参数

-flag [+/-]name

开启或关闭对应名称的参数,只有被标记为manageable的参数才可以被动态修改

-flag name=value

设定对应名称的参数

-flags

输出全部的参数

-sysprops

输出系统属性

jmap:导出内存映像文件&内存使用情况

jmap(JVM Memory Map),作用一方面时获取dump文件(堆转储快照文件,二进制文件),它还可以获取目标Java进程的内存相关信息,包括Java堆各区域的使用情况、堆中对象的统计信息、类加载信息等。

开发人员可以在控制台输入命令jmap -help查阅jmap工具的具体使用方法和一些标准选项配置。

官方文档:https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jmap.html

基本语法

 jmap [options] <pid>
 jmap [options] <executable> <core>
 jmap [options] [server_id@] <remote server IP or hostname>

参数说明

options

  • -dump:[live,] format=b, file=<filename>:生成堆转储快照dump文件,live表示只保存堆中存活对象

  • -heap:输出整个堆空间的详细信息,包括GC的使用、堆配置信息,以及内存的使用信息等

  • -histo[:live]:输出堆空间中对象的统计信息,包括类、实例数量和合计容量,live表示只保存堆中存活对象

  • -permstat:以CLassLoader为统计口径输出永久代的内存状态信息(仅在Linux/Solaris平台有效)

  • -finalizerinfo:显示在F-Queue中等待Finalizer线程执行finalize()方法的对象(仅在Linux/Solaris平台有效)

  • -F:当虚拟机进程堆-dump选项没有任何响应时,可使用此选项强制执行生成dump文件(仅在Linux/Solaris平台有效)

  • -J <flag>:传递参数给jmap启动的JVM