查看JVM加載了哪些類
java -verbose[:class|gc|jni]
在輸出設備上顯示虛擬機運行信息。
java -verbose:class
在程序運行的時候有多少類被加載!你可以用verbose:class
來監視,在命令行輸入java -verbose:class XXX
(XXX為程序名),也可以直接在JVM啟動時添加啟動參數-verbose:class
,你會在控制台(或者指定的啟動日志文件,如catalina.out中)看到加載的類的情況。
verbose
和 verbose:class
含義相同,輸出虛擬機裝入的類的信息,顯示的信息格式如下:
[Opened D:\Java\jdk1.6.0_25\jre\lib\rt.jar]
[Loaded java.lang.Object from D:\Java\jdk1.6.0_25\jre\lib\rt.jar]
[Loaded java.io.Serializable from D:\Java\jdk1.6.0_25\jre\lib\rt.jar]
[Loaded java.lang.Comparable from D:\Java\jdk1.6.0_25\jre\lib\rt.jar]
[Loaded java.lang.CharSequence from D:\Java\jdk1.6.0_25\jre\lib\rt.jar]
[Loaded java.lang.String from D:\Java\jdk1.6.0_25\jre\lib\rt.jar]
[Loaded java.lang.reflect.GenericDeclaration from D:\Java\jdk1.6.0_25\jre\lib\rt.jar]
[Loaded java.lang.reflect.Type from D:\Java\jdk1.6.0_25\jre\lib\rt.jar]
[Loaded java.lang.reflect.AnnotatedElement from D:\Java\jdk1.6.0_25\jre\lib\rt.jar]
[Loaded java.lang.Class from D:\Java\jdk1.6.0_25\jre\lib\rt.jar]
[Loaded java.lang.Cloneable from D:\Java\jdk1.6.0_25\jre\lib\rt.jar]
[Loaded java.lang.ClassLoader from D:\Java\jdk1.6.0_25\jre\lib\rt.jar]
[Loaded java.lang.System from D:\Java\jdk1.6.0_25\jre\lib\rt.jar]
[Loaded java.lang.Throwable from D:\Java\jdk1.6.0_25\jre\lib\rt.jar]
當虛擬機報告類找不到或類沖突時可用此參數來診斷來查看虛擬機從裝入類的情況。
說明:
1、可以通過tailf catalina.out > temp.txt
命令,將啟動時的加載日志重定向到特定文件中,方便后續分析。
2、網上有說可以通過jinfo pid方式查看加載的jar包(在java.class.path下),實操發現,列出的結果不完整
java –verbose:gc
在虛擬機發生內存回收時在輸出設備顯示信息,格式如下: [Full GC 256K->160K(124096K), 0.0042708 secs]
該參數用來監視虛擬機內存回收的情況。
public class JvmVerbose
{
/**
* JVM -verbose[:class|gc|jni] 參數測試
* @param args
*/
public static void main(String[] args)
{
JvmVerbose jvmVerbose = new JvmVerbose();
System.gc();
}
}
在這個例子中,一個新的對象被創建,由於它沒有使用,所以該對象迅速地變為可達,程序編譯后,執行命令: java -verbose:gc JvmVerbose
后結果為:
[GC 647K->256K(124096K), 0.0274253 secs]
[Full GC 256K->160K(124096K), 0.0042708 secs]
箭頭前后的數據256K和160K分別表示垃圾收集GC前后所有存活對象使用的內存容量,說明有256K-160K=96K
的對象容量被回收,括號內的數據124096K
為堆內存的總容量,收集所需要的時間是0.0042708
秒(這個時間在每次執行的時候會有所不同)。
java -verbose:jni
使用-verbose:jni
輸出native
方法調用的相關情況,一般用於診斷jni調用錯誤信息。
在虛擬機調用native方法時輸出設備顯示信息,格式如下: [Dynamic-linking native method java.lang.Object.registerNatives ... JNI]
該參數用來監視虛擬機調用本地方法的情況,在發生jni錯誤時可為診斷提供便利。
查看內存中的類的加載信息
不同類加載器加載同一個類也處於不同的命名空間中,在內存中被視為不同的類。因此在處理類沖突時需要確認同名類是否被相同的類加載器加載,這個時候可以使用以下方式。
通過打印出類的內存快照,並加以分析,可以查看類的類加載器信息。
1、先通過ps -ef|grep proc
找出進程號
2、使用dump內存信息到heap.bin文件
使用命令jmap -dump:live,format=b,file=heap.bin pid(進程號)
將進程pid的堆棧信息輸出到heap.bin文件中
zqq@linux:~/logs> jmap -dump:live,format=b,file=heap.bin 16597
Dumping heap to /home/logs/heap.bin ...
Heap dump file created
3、使用jhat 對heap.bin 文件進行分析
命令jhat -J-mx512m heap.bin
, 如果解析過程中出現內存不足,需要加大內存如:jhat -J-mx800m heap.bin
zqq@linux:~/logs> jhat -J-mx512m heap.bin
Reading from heap.bin...
Dump file created Mon Jun 11 15:34:53 CST 2018
Snapshot read, resolving...
Resolving 448749 objects...
Chasing references, expect 89 dots.........................................................................................
Eliminating duplicate references.........................................................................................
Snapshot resolved.
Started HTTP server on port 7000
Server is ready.
通過瀏覽器訪問 http://ip:7000/
即可看到分析結果。點擊每個類,可以查看詳細信息,包括該類是被哪個類加載器加載。
Package com.adventnet.agent.utilities.xml
class com.adventnet.agent.utilities.xml.XMLDataReader [0x602155cf0]
class com.adventnet.agent.utilities.xml.XMLDataWriter [0x602138950]
class com.adventnet.agent.utilities.xml.XMLIndenter [0x60211c800]
class com.adventnet.agent.utilities.xml.XMLNode [0x602155c70]
Package com.ctc.wstx.api
class com.ctc.wstx.api.CommonConfig [0x6005e7d00]
class com.ctc.wstx.api.ReaderConfig [0x6005e7df0]
class com.ctc.wstx.api.WstxInputProperties [0x6005e9bf0]
class com.ctc.wstx.api.WstxInputProperties$ParsingMode [0x6005ea570]