java虚拟机经常使用命令工具

转自:https://www.iteye.com/blog/learnworld-1381949
如下工具可前往官网查看详情:https://docs.oracle.com/javase/1.5.0/docs/tooldocs/html

1.Java经常使用命令

jps:查看本机的Java进程信息(显示系统中全部Hotspot虚拟机进程)
jstack:打印线程的栈信息,制做线程Dump(显示虚拟机的线程栈信息)
jmap:打印内存映射,只作堆Dump(用于生成虚拟机的内存快照信息)
jinfo:显示虚拟机的配置信息
jstat:性能监视工具(收集Hotspot虚拟机各方面运行数据)
jhat:内存分析工具
jconsole:简易的可视化控制台
jvisualvm:功能强大的控制台
打印某个类的常量池:javap -v Test.class
查看类的加载顺序:java -verbose:class Test
反编译字节码:javap -v -c Testjava

2.什么是Java Dump?有什么用?

Java Dump就是虚拟机的运行时快照,其将Java虚拟机运行时的状态和信息保存到文件中去。做用:能够了解程序运行时,虚拟机中的运行时状态信息;针对非业务逻辑性的BUG,如内存泄漏、内存溢出等。c++

3.制做Java Dump

使用Java虚拟机制做Dump:
-xx:+HeapDumpOnOutOfMemoryError 指示虚拟机在发生内存不足错误时,自动生成堆Dump。
使用图形工具制做Dump:
使用JDK (1.6) 自带的工具:Java VisualVM
使用命令行制做Dump
jstack:制做线程Dump
jmap:制做堆Dumpbootstrap

4.经常使用命令之jps

命令格式:
jps [options] [hostid]浏览器

显示当前全部Java进程pid的命令。
使用jps -help查看帮助:
$ jps -help
$jps -q
只显示pid,不显示class名称,jar文件名和传递给main 方法的参数
$jps -i
输出应用程序main class的完整package名 或者 应用程序的jar文件完整路径名
$jps -v
输出传递给JVM的参数
$jps -m
输出启动时传递给main函数的参数oracle

执行示例:
$ jps -l
3733 sun.tools.jps.Jps
3700 com.leanworld.JVMTools
com.leanworld.JVMTools即为上面的示例代码执行类。框架

5.经常使用命令之javap

javap是jdk自带的一个工具,能够对代码反编译,也能够查看java编译器生成的字节码。
javap命令分解一个class文件,它根据options来决定到底输出什么。若是没有使用options,那么javap将会输出包,类里的protected和public域以及类里的全部方法。javap将会把它们输出在标准输出上。来看这个例子,先编译(javac)下面这个类。
能够尝试:命令行上键入javap DocFooter
加入了-c,即javap -c DocFoote
javap能够用于反编译和查看编译器编译后的字节码。用java -c比较多;该命令用于列出每一个方法所执行的JVM指令,并显示每一个方法的字节码的实际做用。jvm

6.经常使用命令之jstack

命令格式:
jstack [ option ] pidide

jstack是JDK自带的一种堆栈跟踪工具。
jstack用于生成java虚拟机当前时刻的线程快照。线程快照是当前java虚拟机内每一条线程执行的方法堆栈的集合,生成线程快照的主要目的是定位线程长时间停顿的缘由,如线程间死锁、死循环等。线程出现停顿的时候经过jstack来查看各个线程的调用堆栈,就能够知道没有响应的线程到底在后台作什么。若是java程序崩溃,生成core文件,jstack工具能够用来得到core文件的java stack和native stack的信息,从而能够轻松的知道java程序是如何崩溃和在程序何处发出问题。
尝试:jstack -help
-l 长列表,打印关于锁的附加信息;-F 当-l没有响应时强制打印栈信息;-m 打印java和native/c/c++框架的全部栈信息;pid用jps查询。
在死锁时能够查看观察函数

执行示例:

$ 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++调用的堆栈信息

7.经常使用命令之jmap

命令格式:
jmap [ option ] pid

jmap主要用于打印指定Java进程的共享内存映射或堆内存细节,能够用jmap生成堆Dump。
什么是堆Dump?
是反映内存使用状况的内存镜像,其中主要包括系统信息、虚拟机属性、完整的线程Dump、全部类和对象的状态等。通常在GC异常、内存不足的状况下,咱们怀疑又内存泄漏,这时候咱们就能够制做Heap Dump来查看状况,分析缘由。
尝试:输入jmap,会出现-help的信息
查看内存使用状况,用jmap -heap pid
产看堆内存(histogram)中的对象数量及大小,用jmap -histo pid(用histo:live时,会先触发gc,而后统计信息)
将内存使用状况输出到文件,执行的命令是:jmap -dump:fomat=b,file=heapDump pid,而后用jhat命令能够参看:jhat -port 5000 heapDump,而后在浏览器中访问:http:localhost:5000/产看信息

执行示例:
$ 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的统计信息。

8.jstat

命令格式:
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编译的方法.

9.jinfo

命令格式:
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()信息.

注:
    一、若是程序内存不足或频繁GC时,极可能存在内存泄漏的状况,此时就能够借助Java堆Dump查看对象的状况。
    二、制做heap Dump 能够用jamp命令
    三、能够先用jmap -heap查看内存的使用状况
    四、使用jamp -histo:[live] 查看堆内存的使用状况,若是大量对象在持续被引用,并无释放掉,则产生了内存泄漏,就要结合代码,把不用的对象释放掉。
    五、也能够用jmap -dump:format=b,file=<fileName> pid 将堆信息保存到文件中,而后用jhat产看。
    六、若是出现内存泄漏等状况,建议多Dump几回。

实战代码:
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]; }

相关文章
相关标签/搜索