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]; }

相關文章
相關標籤/搜索