一、概述
程序运行中经常会遇到各种问题,定位问题时通常需要综合各种信息,如系统日志、堆dump文件、线程dump文件、GC日志等。通过虚拟机监控和诊断工具可以帮忙我们快速获取、分析需要的数据,进而提高问题解决速度。 本文将介绍虚拟机常用监控和问题诊断命令工具的使用方法,主要包含以下工具:
jps | 显示系统中所有Hotspot虚拟机进程 |
jstat | 收集Hotspot虚拟机各方面运行数据 |
jstack | 显示虚拟机的线程栈信息 |
jinfo | 显示虚拟机的配置信息 |
jmap | 用于生成虚拟机的内存快照信息 |
以上工具的官方文档地址: http://docs.oracle.com/javase/1.5.0/docs/tooldocs/
图形化工具如jconsole,jvisualvm将另文介绍。
二、示例代码
为方便大家使用各工具进行实战,提供样例代码如下:
package com.leanworld; import java.util.ArrayList; import java.util.List; /** * 虚拟机常用工具使用示例代码 启动参数: -Xmn10m -Xms40m -Xmx40m * * @author learnworld 2012-1-30 下午01:37:14 */ public class JVMTools { public static void createList(int count) throws InterruptedException { for (int j = 0; j < count; j++) { List<_1MObject> list = new ArrayList<_1MObject>(); Thread.sleep(100); list.add(new _1MObject()); } } public static void main(String[] args) throws InterruptedException { createList(5000); } } /** * 一个大约1M的对象 */ class _1MObject { public byte[] _1M = new byte[1024 * 1024]; }
三、工具介绍
1. jps
JVM Process Status Tool,该命令用于列出正在运行的虚拟机进程,显示main类的名称和虚拟机进程id。该命令受当前用户的访问权限影响,比如linux下非root用户只列出当前用户启动的虚拟机进程。
命令格式:
jps [options] [hostid]
执行示例:
$ jps -l
3733 sun.tools.jps.Jps
3700 com.leanworld.JVMTools
com.leanworld.JVMTools即为上面的示例代码执行类。
常用参数:
-l | 输出主类全名 |
-v | 输出虚拟机进程启动的jvm参数 |
-m | 输出启动时传递给main函数的参数 |
2. jstat
JVM Statistics Monitoring Tool,用于监控各种运行状态信息的命令。在只有文本控制台的环境中(如企业中的生产环境),该工具非常有用。 可以用来显示系统中类装载、垃圾回收、运行期编译状况等运行数据。
命令格式:
jstat [ generalOption | outputOptions vmid [interval[s|ms] [count]] ]
vmid表示虚拟机唯一标识符,如果是本地虚拟机进程,与LVMID一致,通常为本地虚拟机进程号。 interval表示查询间隔时间,count表示查询次数。如果省略interval和count参数,表示查询一次。
执行示例:
$ jstat -gcutil 3700 500 4
S0 S1 E O P YGC YGCT FGC FGCT GCT
50.00 0.00 60.78 0.50 12.76 214 0.049 0 0.000 0.049
0.00 25.00 20.27 0.50 12.76 215 0.049 0 0.000 0.049
0.00 25.00 70.91 0.50 12.76 215 0.049 0 0.000 0.049
50.00 0.00 20.27 0.50 12.76 216 0.049 0 0.000 0.049
S0和S1表示Survivor0和Survivor1,E表示新生代Eden,O表示老年代Old,P表示持久代Permanent,以上各参数值表示已使用空间占比。 YGC表示young gc次数,YGCT表示young gc总耗时。FGC表示Full gc次数,FGCT表示full gc总耗时。GCT表示所有gc总耗时时间。
常用参数:
class | 类装载相关信息. |
compiler | JIT编译器编译过的方法、耗时等. |
gc | java堆信息和垃圾回收状况. |
gccapacity | 关注java堆各个区的最大和最小空间. |
gccause | 类似gcutil,额外输出导致上一次gc的原因. |
gcnew | 新生代gc状况. |
gcnewcapacity | 关注新生代gc使用的最大和最小空间. |
gcold | 老年代gc状况. |
gcoldcapacity | 关注老年代gc使用的最大和最小空间. |
gcpermcapacity | 关注持久代gc使用的最大和最小空间. |
gcutil | 关注已使用空间占总空间比例. |
printcompilation | 输出已经被JIT编译的方法. |
3. jstack
Stack Trace for Java,用于生成虚拟机当前的线程快照信息,包含每一条线程的堆栈信息。该命令通常用于定位线程停顿原因,当出现线程停顿时,可通过stack查看每个线程的堆栈信息,进而分析停顿原因。
命令格式:
jstack [ option ] pid
执行示例:
$ jstack 3700
2012-01-30 16:36:05
Full thread dump Java HotSpot(TM) Server VM (17.0-b16 mixed mode):
"Attach Listener" daemon prio=10 tid=0xaca16c00 nid=0x1384 waiting on condition [0x00000000]
java.lang.Thread.State: RUNNABLE
"Low Memory Detector" daemon prio=10 tid=0xaca00c00 nid=0x1366 runnable [0x00000000]
java.lang.Thread.State: RUNNABLE
"CompilerThread1" daemon prio=10 tid=0x08e58800 nid=0x1365 waiting on condition [0x00000000]
java.lang.Thread.State: RUNNABLE
"CompilerThread0" daemon prio=10 tid=0x08e56800 nid=0x1364 waiting on condition [0x00000000]
java.lang.Thread.State: RUNNABLE
"Signal Dispatcher" daemon prio=10 tid=0x08e54c00 nid=0x1363 runnable [0x00000000]
java.lang.Thread.State: RUNNABLE
"Finalizer" daemon prio=10 tid=0x08e39000 nid=0x1361 in Object.wait() [0xac943000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0xb10e0230> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:118)
- locked <0xb10e0230> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:134)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:159)
"Reference Handler" daemon prio=10 tid=0x08e34400 nid=0x1360 in Object.wait() [0xacb94000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0xb10e30d0> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Object.java:485)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:116)
- locked <0xb10e30d0> (a java.lang.ref.Reference$Lock)
"main" prio=10 tid=0x08d7bc00 nid=0x135a waiting on condition [0xb6a8a000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at com.leanworld.JVMTools.createList(JVMTools.java:23)
at com.leanworld.JVMTools.main(JVMTools.java:29)
"VM Thread" prio=10 tid=0x08e31c00 nid=0x135f runnable
"GC task thread#0 (ParallelGC)" prio=10 tid=0x08d83800 nid=0x135b runnable
"GC task thread#1 (ParallelGC)" prio=10 tid=0x08d85000 nid=0x135c runnable
"GC task thread#2 (ParallelGC)" prio=10 tid=0x08d86400 nid=0x135d runnable
"GC task thread#3 (ParallelGC)" prio=10 tid=0x08d87c00 nid=0x135e runnable
"VM Periodic Task Thread" prio=10 tid=0xaca02c00 nid=0x1367 waiting on condition
JNI global references: 854
通过输出信息可以看出当前main线程处于TIMED_WAITING状态,因为执行到示例代码中Thread.sleep(100);这行的缘故。
常用参数:
-l | 除堆栈外,显示锁的附加信息 |
-F | 当请求不被响应时,强制输出线程堆栈 |
-m | 混合模式,打印java和本地C++调用的堆栈信息 |
4. jinfo
Configuration Info for Java,用于查看和修改虚拟机的各项参数信息。
命令格式:
jinfo [ option ] pid
执行示例:
$jinfo 3700
Attaching to process ID 5081, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 17.0-b16
Java System Properties:
java.runtime.name = Java(TM) SE Runtime Environment
sun.boot.library.path = /home/learnworld/software/jdk1.6.0_21/jre/lib/i386
java.vm.version = 17.0-b16
java.vm.vendor = Sun Microsystems Inc.
java.vendor.url = http://java.sun.com/
path.separator = :
java.vm.name = Java HotSpot(TM) Server VM
file.encoding.pkg = sun.io
sun.java.launcher = SUN_STANDARD
user.country = CN
sun.os.patch.level = unknown
java.vm.specification.name = Java Virtual Machine Specification
user.dir = /home/learnworld/workspace/concurrency
java.runtime.version = 1.6.0_21-b06
java.awt.graphicsenv = sun.awt.X11GraphicsEnvironment
java.endorsed.dirs = /home/learnworld/software/jdk1.6.0_21/jre/lib/endorsed
os.arch = i386
java.io.tmpdir = /tmp
line.separator =
...
VM Flags:
-Xmn10m -Xms40m -Xmx40m -Dfile.encoding=GBK -Xbootclasspath:/home/learnworld/software/jdk1.6.0_21/lib/tools.jar:/home/learnworld/software/jdk1.6.0_21/lib/sa-jdi.jar:/home/learnworld/software/jdk1.6.0_21/lib/jconsole.jar:/home/learnworld/software/jdk1.6.0_21/lib/htmlconverter.jar:/home/learnworld/software/jdk1.6.0_21/lib/dt.jar:/home/learnworld/software/jdk1.6.0_21/jre/lib/rt.jar:/home/learnworld/software/jdk1.6.0_21/jre/lib/resources.jar:/home/learnworld/software/jdk1.6.0_21/jre/lib/plugin.jar:/home/learnworld/software/jdk1.6.0_21/jre/lib/management-agent.jar:/home/learnworld/software/jdk1.6.0_21/jre/lib/jsse.jar:/home/learnworld/software/jdk1.6.0_21/jre/lib/jce.jar:/home/learnworld/software/jdk1.6.0_21/jre/lib/javaws.jar:/home/learnworld/software/jdk1.6.0_21/jre/lib/deploy.jar:/home/learnworld/software/jdk1.6.0_21/jre/lib/charsets.jar:/home/learnworld/software/jdk1.6.0_21/jre/lib/alt-rt.jar
可以看出,该命令可以方便我们查找需要的虚拟机信息,包含System.getProperties()信息。
常用参数:
-flag name | 打印虚拟机该参数对应的值. |
-flag [+\-]name | 使该参数生效或失效. |
-flag name=value | 修改相应参数的值. |
-flags | 打印传给jvm的参数值. |
-sysprops | 打印System.getProperties()信息. |
5. jmap
Memory Map for Java,可以产生堆dump文件,查询堆和持久代的详细信息等。
命令格式:
jmap [ option ] pid
执行示例:
$ jmap -dump:format=b,file=dump.tmp 3700
Dumping heap to /home/learnworld/dump.tmp ...
Heap dump file created
上面这个命令生成了dump.tmp这个dump文件。生成的dump文件可以使用Eclipse Memory Analyzer/jhat等工具进行分析。
$ jmap -permstat 3700
Attaching to process ID 3700, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 17.0-b16
1355 intern Strings occupying 183024 bytes.
finding class loader instances ..Finding object size using Printezis bits and skipping over...
done.
computing per loader stat ..done.
please wait.. computing liveness....done.
class_loader classes bytes parent_loader alive? type
<bootstrap> 320 1437208 null live <internal>
0xb1170250 10 77120 0xb11706b8 live sun/misc/Launcher$AppClassLoader@0xad34eb70
0xb11706b8 0 0 null live sun/misc/Launcher$ExtClassLoader@0xad303d40
total = 3 330 1514328 N/A alive=3, dead=0 N/A
常用参数:
-dump | 生成堆dump文件,格式为: -dump:[live,]format=b,file=<filename> |
-heap | 显示java堆的详细信息,包括垃圾回收期、堆配置和分代信息等 |
-histo | 显示堆中对象的统计信息,包括类名称,对应的实例数量和总容量 |
-permstat | 统计持久代中各ClassLoader的统计信息。 |
四、遇到的问题
我的操作系统为ubuntu10.10,初次使用jinfo和jmap时出现以下错误:
Error attaching to process: sun.jvm.hotspot.debugger.DebuggerException: Can't attach to the process
解决方法:
1. echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope
该方法在下次重启前有效。
2. 永久有效方法
sudo vi /etc/sysctl.d/10-ptrace.conf
编辑下面这行:
kernel.yama.ptrace_scope = 1
修改为:
kernel.yama.ptrace_scope = 0
重启系统,使修改生效。
该bug详细信息请参考官方文档: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7050524
相关推荐
在Java虚拟机运行过程中,我们可能需要使用各种命令工具来监控和诊断可能出现的问题。以下是一些常用的JVM命令工具及其知识点。 1. jps命令 jps(JVM Process Status Tool)命令用于列出正在运行的Java虚拟机进程...
JVM即Java虚拟机,是Java平台的核心组成部分,使得Java可以实现“一次编写,到处运行”的跨平台特性。JVM不是跨平台的,而是其在不同操作系统(如Windows、Linux、macOS)上的实现保证了Java程序能够在这些平台上无...
Java虚拟机调优及问题排查手册 本手册主要介绍Java虚拟机(JVM)的调优和问题排查解决方案。该手册涵盖了JVM排查、数据库连接排查、堆栈快照排查等多方面的内容。 JVM排查 JVM排查是指通过各种命令和工具来排查...
### 查看虚拟机状态常用命令解析 在日常的IT运维工作中,经常需要对虚拟机的状态进行监控和管理,以确保其稳定高效地运行。本文将详细介绍一些常用的虚拟机状态查看命令,包括`jmap`, `jstat`, `jstat-gcutil`等...
### 五、常用的JVM问题分析命令工具 - **jps**:查看Java进程,可以使用选项 `-q` 只显示进程ID,`-m` 输出传递给main方法的参数,`-l` 输出完整包名或jar路径,`-v` 输出JVM参数。 - **jmap**:分析Java进程的内存...
### jvm常用命令工具 #### 一、概述 在程序运行过程中,经常会出现各种各样的问题,例如性能瓶颈、内存泄漏、死锁等。为了快速定位并解决问题,我们需要收集多种类型的运行时信息,包括但不限于系统日志、堆转储...
### Java虚拟机(JVM)面试宝典核心知识点详解 #### 一、Java内存区域 **1.1 JVM的主要组成部分及其作用** JVM的核心组件包括两个子系统和两个组件: - **Classloader(类装载器)**:负责根据给定的全限定名(如 ...
jps 命令用于列出目标系统上正在运行的虚拟机进程(每个 Java 程序会独占一个 Java 虚拟机实例)。所列信息包括进程 ID 及虚拟机执行主类名称,对于非 root 账户,只能显示当前用户启动的虚拟机进程。 参数详解: ...
Linux常用命令汇总中,首先涉及到的是检查Java开发工具包(JDK)是否已安装以及版本信息。使用命令`java –version`和`javac –version`可以实现该功能。`java –version`用于查看Java运行环境的版本,而`javac –...
### 深入学习JVM(Java虚拟机)内核教程知识点详解 #### 1. JVM运行机制 - **概述**:JVM是Java程序在计算机上运行的基础平台,它负责将Java字节码转换为特定平台上的机器指令并执行。 - **主要组件**: - **类...
它是Java程序员必不可少的一套工具集合,包含了Java运行环境(JRE)、Java虚拟机(JVM)、Java工具(如编译器、调试器等)和Java基础类库。 - **作用**:JDK提供了开发Java应用程序所需的环境,包括编译、调试和运行...
4. 平台无关性:Java的字节码(.class文件)可以在任何支持Java的平台上运行,这是因为Java虚拟机(JVM)负责将字节码解释为特定平台的机器指令。这一特性使得Java程序具有“一次编写,到处运行”的优势。 5. 安全...
例如,`javac`和`java`命令是日常开发中最常用的,而`jconsole`和`jvisualvm`则在性能调优时发挥重要作用。随着Java版本的更新,新的特性和工具也会不断引入,以适应不断变化的开发需求和技术趋势。因此,定期更新...
9. **jstat**:Java虚拟机统计监测工具 `jstat`用于收集JVM的运行时统计信息,包括垃圾收集、类装载、编译器等。例如,`jstat -gc <pid> 1000 5`会每秒收集一次GC信息,共收集5次。 10. **jinfo**:配置信息工具 ...
`javap`可以查看类文件的字节码信息,这对于理解Java虚拟机的工作原理很有帮助。例如,`javap -c HelloWorld`会显示HelloWorld.class的反汇编信息。 6. **jconsole**和**jvisualvm**:Java性能监控工具 这两个...
IBM内存分析工具(IBM Memory Analyzer,简称MAT)是一款强大的、免费的诊断工具,适用于所有Java虚拟机(JVM)。它能够提供详细的内存分配和引用路径信息,帮助开发者深入理解内存消耗情况,找出可能导致内存问题...
4. **jstat (Java Statistics Tool)**: 这个命令主要用于收集Java虚拟机的各种统计数据,如垃圾收集、类加载等。例如,`jstat -gc pid [interval] [count]` 可以监控新老生代的内存使用和垃圾回收频率。使用`jstat -...
掌握JDK的常用命令对于Java开发者来说非常重要,因为这些命令是实现Java程序编写、编译、调试、文档化、打包和部署的基本手段。 首先,我们需要了解JDK的安装目录。通常,我们会设置JAVA_HOME环境变量指向JDK的安装...
Linux是开源且自由的操作系统,深受Java开发者喜爱,因为它提供了稳定的服务器环境,支持各种开发工具,并且具有良好的可定制性。对于Java开发者来说,掌握一些基础的Linux命令是必要的技能,这有助于提升开发效率和...
`rt.jar`这个名字是“Runtime”的缩写,它存储了Java虚拟机(JVM)在运行时需要的所有类和接口。例如,`java.lang.Object`是所有Java类的基类,`java.util.ArrayList`是常用的集合类,`java.io.File`用于文件操作,...