Java內(nèi)存泄露監(jiān)控工具:JVM監(jiān)控工具介紹
jstack -- 如果java程序崩潰生成core文件,jstack工具可以用來獲得core文件的java stack和native stack的信息,從而可以輕松地知道java程序是如何崩潰和在程序何處發(fā)生問題。另外,jstack工具還可以附屬到正在運(yùn)行的java程序中,看到 當(dāng)時(shí)運(yùn)行的java程序的java stack和native stack的信息, 如果現(xiàn)在運(yùn)行的java程序呈現(xiàn)hung的狀態(tài),jstack是非常有用的。目前只有在Solaris和Linux的JDK版本里面才有。
jconsole – jconsole是基于Java Management Extensions (JMX)的實(shí)時(shí)圖形化監(jiān)測工具,這個(gè)工具利用了內(nèi)建到JVM里面的JMX指令來提供實(shí)時(shí)的性能和資源的監(jiān)控,包括了Java 程序的內(nèi)存使用,Heap size, 線程的狀態(tài),類的分配狀態(tài)和空間使用等等。
jinfo – jinfo可以從core文件里面知道崩潰的Java應(yīng)用程序的配置信息,目前只有在Solaris和Linux的JDK版本里面才有。
jmap – jmap 可以從core文件或進(jìn)程中獲得內(nèi)存的具體匹配情況,包括Heap size, Perm size等等,目前只有在Solaris和Linux的JDK版本里面才有。
jdb – jdb 用來對core文件和正在運(yùn)行的Java進(jìn)程進(jìn)行實(shí)時(shí)地調(diào)試,里面包含了豐富的命令幫助您進(jìn)行調(diào)試,它的功能和Sun studio里面所帶的dbx非常相似,但 jdb是專門用來針對Java應(yīng)用程序的。
jstat – jstat利用了JVM內(nèi)建的指令對Java應(yīng)用程序的資源和性能進(jìn)行實(shí)時(shí)的命令行的監(jiān)控,包括了對Heap size和垃圾回收狀況的監(jiān)控等等。
jps – jps是用來查看JVM里面所有進(jìn)程的具體狀態(tài), 包括進(jìn)程ID,進(jìn)程啟動(dòng)的路徑等等。
jstatd
啟動(dòng)jvm監(jiān)控服務(wù)。它是一個(gè)基于rmi的應(yīng)用,向遠(yuǎn)程機(jī)器提供本機(jī)jvm應(yīng)用程序的信息。默認(rèn)端口1099。
實(shí)例:jstatd -J-Djava.security.policy=my.policy
my.policy文件需要自己建立,內(nèi)如如下:
- grant codebase "file:$JAVA_HOME/lib/tools.jar" {
- permission java.security.AllPermission;
- };
這是安全策略文件,因?yàn)閖dk對jvm做了jaas的安全檢測,所以我們必須設(shè)置一些策略,使得jstatd被允許作網(wǎng)絡(luò)操作
上面的操作沒有通過,出現(xiàn):
Could not create remote object
access denied (java.util.PropertyPermission java.rmi.server.ignoreSubClasses write)
java.security.AccessControlException: access denied (java.util.PropertyPermission java.rmi.server.ignoreSubClasses write)
at java.security.AccessControlContext.checkPermission(AccessControlContext.java:323)
at java.security.AccessController.checkPermission(AccessController.java:546)
at java.lang.SecurityManager.checkPermission(SecurityManager.java:532)
at java.lang.System.setProperty(System.java:727)
at sun.tools.jstatd.Jstatd.main(Jstatd.java:122)
create in your usr/java/bin the jstatd.all.policy file, with the content must be
- grant codebase "file:${java.home}/../lib/tools.jar" {
- permission java.security.AllPermission;
- };
JPS
列出所有的jvm實(shí)例
實(shí)例:
jps
列出本機(jī)所有的jvm實(shí)例
jps 192.168.0.77
列出遠(yuǎn)程服務(wù)器192.168.0.77機(jī)器所有的jvm實(shí)例,采用rmi協(xié)議,默認(rèn)連接端口為1099(前提是遠(yuǎn)程服務(wù)器提供jstatd服務(wù))
輸出內(nèi)容如下:
jones@jones:~/data/ebook/java/j2se/jdk_gc$ jps 6286 Jps 6174 Jstat
jconsole
一個(gè)圖形化界面,可以觀察到j(luò)ava進(jìn)程的gc,class,內(nèi)存等信息。雖然比較直觀,但是個(gè)人還是比較傾向于使用jstat命令(在最后一部分會對jstat作詳細(xì)的介紹)。
jinfo (linux下特有)
觀察運(yùn)行中的java程序的運(yùn)行環(huán)境參數(shù):參數(shù)包括Java System屬性和JVM命令行參數(shù)
實(shí)例:jinfo 2083
其中2083就是java進(jìn)程id號,可以用jps得到這個(gè)id號。
輸出內(nèi)容太多了,不在這里一一列舉,大家可以自己嘗試這個(gè)命令。
jstack (linux下特有)
可以觀察到j(luò)vm中當(dāng)前所有線程的運(yùn)行情況和線程當(dāng)前狀態(tài)
jstack 2083
輸出內(nèi)容如下:
jmap (linux下特有,也是很常用的一個(gè)命令)
觀察運(yùn)行中的jvm物理內(nèi)存的占用情況。
參數(shù)如下:
-heap :打印jvm heap的情況
-histo: 打印jvm heap的直方圖。其輸出信息包括類名,對象數(shù)量,對象占用大小。
-histo:live : 同上,但是只答應(yīng)存活對象的情況
-permstat: 打印permanent generation heap情況
命令使用:
jmap -heap 2083
可以觀察到New Generation(Eden Space,F(xiàn)rom Space,To Space),tenured generation,Perm Generation的內(nèi)存使用情況
輸出內(nèi)容:
jmap -histo 2083 | jmap -histo:live 2083
可以觀察heap中所有對象的情況(heap中所有生存的對象的情況)。包括對象數(shù)量和所占空間大小。
輸出內(nèi)容:
寫個(gè)腳本,可以很快把占用heap最大的對象找出來,對付內(nèi)存泄漏特別有效。
jstat
最后要重點(diǎn)介紹下這個(gè)命令。
這是jdk命令中比較重要,也是相當(dāng)實(shí)用的一個(gè)命令,可以觀察到classloader,compiler,gc相關(guān)信息
具體參數(shù)如下:
-class:統(tǒng)計(jì)class loader行為信息
-compile:統(tǒng)計(jì)編譯行為信息
-gc:統(tǒng)計(jì)jdk gc時(shí)heap信息
-gccapacity:統(tǒng)計(jì)不同的generations(不知道怎么翻譯好,包括新生區(qū),老年區(qū),permanent區(qū))相應(yīng)的heap容量情況
-gccause:統(tǒng)計(jì)gc的情況,(同-gcutil)和引起gc的事件
-gcnew:統(tǒng)計(jì)gc時(shí),新生代的情況
-gcnewcapacity:統(tǒng)計(jì)gc時(shí),新生代heap容量
-gcold:統(tǒng)計(jì)gc時(shí),老年區(qū)的情況
-gcoldcapacity:統(tǒng)計(jì)gc時(shí),老年區(qū)heap容量
-gcpermcapacity:統(tǒng)計(jì)gc時(shí),permanent區(qū)heap容量
-gcutil:統(tǒng)計(jì)gc時(shí),heap情況
-printcompilation:不知道干什么的,一直沒用過。
一般比較常用的幾個(gè)參數(shù)是:
jstat -class 2083 1000 10 (每隔1秒監(jiān)控一次,一共做10次)
輸出內(nèi)容含義如下:
Loaded | Number of classes loaded. |
Bytes | Number of Kbytes loaded. |
Unloaded | Number of classes unloaded. |
Bytes | Number of Kbytes unloaded. |
Time | Time spent performing class load and unload operations. |
jstat -gc 2083 2000 20(每隔2秒監(jiān)控一次,共做10)
輸出內(nèi)容含義如下:
S0C | Current survivor space 0 capacity (KB). |
EC | Current eden space capacity (KB). |
EU | Eden space utilization (KB). |
OC | Current old space capacity (KB). |
OU | Old space utilization (KB). |
PC | Current permanent space capacity (KB). |
PU | Permanent space utilization (KB). |
YGC | Number of young generation GC Events. |
YGCT | Young generation garbage collection time. |
FGC | Number of full GC events. |
FGCT | Full garbage collection time. |
GCT | Total garbage collection time. |
輸出內(nèi)容:
如果能熟練運(yùn)用這些命令,尤其是在linux下,那么完全可以代替jprofile等監(jiān)控工具了,誰讓它收費(fèi)呢。呵呵。
用命令的好處就是速度快,并且輔助于其他命令,比如grep gawk sed等,可以組裝多種符合自己需求的工具。
- jps 的用法
用來查看 JVM 里面所有進(jìn)程的具體狀態(tài) , 包括進(jìn)程 ID ,進(jìn)程啟動(dòng)的路徑等等。 與 unix 上的 ps 類似,用來顯示本地的 java 進(jìn)程,可以查看本地運(yùn)行著幾個(gè) java 程序,并顯示他們的進(jìn)程號。
[root@localhost ~]# jps
25517 Jps
25444 Bootstrap
- jstack 的用法
如果 java 程序崩潰生成 core 文件, jstack 工具可以用來獲得 core 文件的 java stack 和 native stack 的信息,從而可以輕松地知道 java 程序是如何崩潰和在程序何處發(fā)生問題。另外, jstack 工具還可以附屬到正在運(yùn)行的 java 程序中,看到當(dāng)時(shí)運(yùn)行的 java 程序的 java stack 和 native stack 的信息 , 如果現(xiàn)在運(yùn)行的 java 程序呈現(xiàn) hung 的狀態(tài), jstack 是非常有用的。目前只有在 Solaris 和 Linux 的 JDK 版本里面才有。
[root@localhost bin]# jstack 25444
Attaching to process ID 25917, please wait...
Debugger attached successfully.
Client compiler detected.
JVM version is 1.5.0_08-b03
Thread 25964: (state = BLOCKED)
Error occurred during stack walking:
sun.jvm.hotspot.debugger.DebuggerException: sun.jvm.hotspot.debugger.DebuggerException: get_thread_regs failed for a lwp
at sun.jvm.hotspot.debugger.linux.LinuxDebuggerLocal$LinuxDebuggerLocalWorkerThread.execute(LinuxDebuggerLocal.java:134)
at sun.jvm.hotspot.debugger.linux.LinuxDebuggerLocal.getThreadIntegerRegisterSet(LinuxDebuggerLocal.java:437)
at sun.jvm.hotspot.debugger.linux.LinuxThread.getContext(LinuxThread.java:48)
at
- jstat 的用法
用以判斷JVM 是否存在內(nèi)存問題呢?如何判斷JVM 垃圾回收是否正常?一般的top 指令基本上滿足不了這樣的需求,因?yàn)樗饕O(jiān)控的是總體的系統(tǒng)資源,很難定位到j(luò)ava 應(yīng)用程序。
Jstat 是JDK 自帶的一個(gè)輕量級小工具。全稱“Java Virtual Machine statistics monitoring tool” ,它位于java 的bin 目錄下,主要利用JVM 內(nèi)建的指令對Java 應(yīng)用程序的資源和性能進(jìn)行實(shí)時(shí)的命令行的監(jiān)控,包括了對Heap size 和垃圾回收狀況的監(jiān)控??梢?,Jstat 是輕量級的、專門針對JVM 的工具,非常適用。由于JVM 內(nèi)存設(shè)置較大,圖中百分比變化不太明顯
一個(gè)極強(qiáng)的監(jiān)視 VM 內(nèi)存工具。可以用來監(jiān)視 VM 內(nèi)存內(nèi)的各種堆和非堆的大小及其內(nèi)存使用量。
jstat 工具特別強(qiáng)大,有眾多的可選項(xiàng),詳細(xì)查看堆內(nèi)各個(gè)部分的使用量,以及加載類的數(shù)量。使用時(shí),需加上查看進(jìn)程的進(jìn)程 id ,和所選參數(shù)。
語法結(jié)構(gòu):
Usage: jstat -help|-options
jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]
參數(shù)解釋:
Options — 選項(xiàng),我們一般使用 -gcutil 查看gc 情況
vmid — VM 的進(jìn)程號,即當(dāng)前運(yùn)行的java 進(jìn)程號
interval– 間隔時(shí)間,單位為秒或者毫秒
count — 打印次數(shù),如果缺省則打印無數(shù)次
S0 — Heap 上的 Survivor space 0 區(qū)已使用空間的百分比
S1 — Heap 上的 Survivor space 1 區(qū)已使用空間的百分比
E — Heap 上的 Eden space 區(qū)已使用空間的百分比
O — Heap 上的 Old space 區(qū)已使用空間的百分比
P — Perm space 區(qū)已使用空間的百分比
YGC — 從應(yīng)用程序啟動(dòng)到采樣時(shí)發(fā)生 Young GC 的次數(shù)
YGCT– 從應(yīng)用程序啟動(dòng)到采樣時(shí) Young GC 所用的時(shí)間( 單位秒 )
FGC — 從應(yīng)用程序啟動(dòng)到采樣時(shí)發(fā)生 Full GC 的次數(shù)
FGCT– 從應(yīng)用程序啟動(dòng)到采樣時(shí) Full GC 所用的時(shí)間( 單位秒 )
GCT — 從應(yīng)用程序啟動(dòng)到采樣時(shí)用于垃圾回收的總時(shí)間( 單位秒)
實(shí)例使用1 :
[root@localhost bin]# jstat -gcutil 25444
S0 S1 E O P YGC YGCT FGC FGCT GCT
11.63 0.00 56.46 66.92 98.49 162 0.248 6 0.331 0.579
實(shí)例使用 2 :
[root@localhost bin]# jstat -gcutil 25444 1000 5
S0 S1 E O P YGC YGCT FGC FGCT GCT
73.54 0.00 99.04 67.52 98.49 166 0.252 6 0.331 0.583
73.54 0.00 99.04 67.52 98.49 166 0.252 6 0.331 0.583
73.54 0.00 99.04 67.52 98.49 166 0.252 6 0.331 0.583
73.54 0.00 99.04 67.52 98.49 166 0.252 6 0.331 0.583
73.54 0.00 99.04 67.52 98.49 166 0.252 6 0.331 0.583
我們可以看到,5 次young gc 之后,垃圾內(nèi)存被從Eden space 區(qū)(E) 放入了Old space 區(qū)(O) ,并引起了百分比的變化,導(dǎo)致Survivor space 使用的百分比從73.54%(S0) 降到0%(S1) 。有效釋放了內(nèi)存空間。綠框中,我們可以看到,一次full gc 之后,Old space 區(qū)(O) 的內(nèi)存被回收,從99.05% 降到67.52% 。
圖中同時(shí)打印了young gc 和full gc 的總次數(shù)、總耗時(shí)。而,每次young gc 消耗的時(shí)間,可以用相間隔的兩行YGCT 相減得到。每次full gc 消耗的時(shí)間,可以用相隔的兩行FGCT 相減得到。例如紅框中表示的第一行、第二行之間發(fā)生了1 次young gc ,消耗的時(shí)間為0.252-0.252 =0.0 秒。
常駐內(nèi)存區(qū)(P) 的使用率,始終停留在98.49% 左右,說明常駐內(nèi)存沒有突變,比較正常。
如果young gc 和full gc 能夠正常發(fā)生,而且都能有效回收內(nèi)存,常駐內(nèi)存區(qū)變化不明顯,則說明java 內(nèi)存釋放情況正常,垃圾回收及時(shí),java 內(nèi)存泄露的幾率就會大大降低。但也不能說明一定沒有內(nèi)存泄露。
GCT 是YGCT 和FGCT 的時(shí)間總和。
以上,介紹了Jstat 按百分比查看gc 情況的功能。其實(shí),它還有功能,例如加載類信息統(tǒng)計(jì)功能、內(nèi)存池信息統(tǒng)計(jì)功能等,那些是以絕對值的形式打印出來的,比較少用,在此就不做介紹。
[root@localhost bin]# ps -ef | grep java
root 25917 1 2 23:23 pts /2 00:00:05 /usr/local/jdk1.5/bin/java -Djava.endorsed.dirs=/usr/local/jakarta-tomcat-5.0.30/common/endorsed -classpath /usr/local/jdk1.5/lib/tools.jar:/usr/local/jakarta-tomcat-5.0.30/bin/bootstrap.jar:/usr/local/jakarta-tomcat-5.0.30/bin/commons-logging-api.jar -Dcatalina.base=/usr/local/jakarta-tomcat-5.0.30 -Dcatalina.home=/usr/local/jakarta-tomcat-5.0.30 -Djava.io.tmpdir=/usr/local/jakarta-tomcat-5.0.30/temp org.apache.catalina.startup.Bootstrap start
jstat -class pid: 顯示加載 class 的數(shù)量,及所占空間等信息。
實(shí)例使用3 :
[root@localhost bin]# jstat -class 25917
Loaded Bytes Unloaded Bytes Time
2629 2916.8 29 24.6 0.90
jstat -compiler pid: 顯示 VM 實(shí)時(shí)編譯的數(shù)量等信息。
實(shí)例使用 4 :
[root@localhost bin]# jstat -compiler 25917
Compiled Failed Invalid Time FailedType FailedMethod
768 0 0 0.70 0
jstat –gccapacity : 可以顯示, VM 內(nèi)存中三代( young,old,perm )對象的使用和占用大小,如: PGCMN 顯示的是最小 perm 的內(nèi)存使用量, PGCMX 顯示的是 perm 的內(nèi)存最大使用量, PGC 是當(dāng)前新生成的 perm 內(nèi)存占用量, PC 是但前 perm 內(nèi)存占用量。其他的可以根據(jù)這個(gè)類推, OC 是 old 內(nèi)純的占用量。
[root@localhost bin]# jstat -gccapacity 25917
NGCMN 640.0
NGCMX 4992.0
NGC 832.0
S0C 64.0
S1C 64.0
EC 704.0
OGCMN 1408.0
OGCMX 60544.0
OGC 9504.0
OC 9504.0 OC 是 old 內(nèi)純的占用量
PGCMN 8192.0 PGCMN 顯示的是最小 perm 的內(nèi)存使用量
PGCMX 65536.0 PGCMX 顯示的是 perm 的內(nèi)存最大使用量
PGC 12800.0 PGC 是當(dāng)前新生成的 perm 內(nèi)存占用量
PC 12800.0 PC 是但前 perm 內(nèi)存占用量
YGC 164
FGC 6
jstat -gcnew pid: new 對象的信息
[root@localhost bin]# jstat -gcnew 25917
S0C S1C S0U S1U TT MTT DSS EC EU YGC YGCT
64.0 64.0 47.4 0.0 2 15 32.0 704.0 145.7 168 0.254
jstat -gcnewcapacity pid: new 對象的信息及其占用量
[root@localhost bin]# jstat -gcnewcapacity 25917
NGCMN NGCMX NGC S0CMX S0C S1CMX S1C ECMX EC YGC FGC
640.0 4992.0 832.0 64.0 448.0 448.0 64.0 4096.0 704.0 168 6
jstat -gcold pid: old 對象的信息。
[root@localhost bin]# jstat -gcold 25917
PC PU OC OU YGC FGC FGCT GCT
12800.0 12617.6 9504.0 6561.3 169 6 0.335 0.591
jstat -gcoldcapacity pid:old 對象的信息及其占用量。
[root@localhost bin]# jstat -gcoldcapacity 25917
OGCMN OGCMX OGC OC YGC FGC FGCT GCT
1408.0 60544.0 9504.0 9504.0 169 6 0.335 0.591
jstat -gcpermcapacity pid: perm 對象的信息及其占用量。
[root@localhost bin]# jstat -gcpermcapacity 25917
PGCMN PGCMX PGC PC YGC FGC FGCT GCT
8192.0 65536.0 12800.0 12800.0 169 6 0.335 0.591
jstat -printcompilation pid: 當(dāng)前 VM 執(zhí)行的信息。
[root@localhost bin]# jstat -printcompilation -h3 25917 1000 5
每 1000 毫秒打印一次,一共打印 5 次,還可以加上 -h3 每三行顯示一下標(biāo)題。
Compiled Size Type Method
788 73 1 java/io/File <init>
788 73 1 java/io/File <init>
788 73 1 java/io/File <init>
Compiled Size Type Method
788 73 1 java/io/File <init>
788 73 1 java/io/File <init>
- jmap 的用法
打印出某個(gè) java 進(jìn)程(使用 pid )內(nèi)存內(nèi)的,所有 ‘ 對象 ’ 的情況(如:產(chǎn)生那些對象,及其數(shù)量)。
可以輸出所有內(nèi)存中對象的工具,甚至可以將 VM 中的 heap ,以二進(jìn)制輸出成文本。使用方法 jmap -histo pid 。如果連用 SHELL jmap -histo pid>a.log 可以將其保存到文本中去,在一段時(shí)間后,使用文本對比工具,可以對比出 GC 回收了哪些對象。 jmap -dump:format=b,file=String 3024 可以將 3024 進(jìn)程的內(nèi)存 heap 輸出出來到 String 文件里。
[root@localhost bin]# jmap -histo 25917
Attaching to process ID 26221, please wait...
Debugger attached successfully.
Client compiler detected.
JVM version is 1.5.0_08-b03
Iterating over heap. This may take a while...
Unknown oop at 0xaa6e42d0
Oop's klass is null
Object Histogram:
Size Count Class description
-------------------------------------------------------
3722768 30467 * ConstMethodKlass
1976480 25334 char[]
1907880 46994 * SymbolKlass
1762088 2947 byte[]
1709536 30467 * MethodKlass
1487816 2600 * ConstantPoolKlass
1009576 2600 * InstanceKlassKlass
904880 2199 * ConstantPoolCacheKlass
741432 30893 java.lang.String
653576 4785 int[]
351760 4397 java.lang.reflect.Method
277824 2894 java.lang.Class
248704 3401 short[]
200888 4411 java.lang.Object[]
193656 4045 java.lang.Object[]
179744 5617 java.util.TreeMap$Entry
175688 1800 java.util.HashMap$Entry[]
165288 6887 java.util.HashMap$Entry
104736 3273 java.lang.ref.SoftReference
104136 4339 java.lang.ref.WeakReference
96096 3521 java.lang.String[]
86160 3590 java.util.Hashtable$Entry
85584 3566 java.util.ArrayList
83472 1206 java.util.Hashtable$Entry[]
82944 1728 java.beans.MethodDescriptor
80560 265 * ObjArrayKlassKlass
69120 1728 java.util.HashMap
52464 3055 java.lang.Class[]
43040 1076 java.util.Hashtable
42496 664 org.apache.commons.modeler.AttributeInfo
37880 947 java.util.TreeMap
33896 557 javax.management.modelmbean.ModelMBeanAttributeInfo[]
33152 518 java.beans.PropertyDescriptor
616 11 org.springframework.aop.framework.ProxyFactory
608 19 java.util.PropertyPermission
608 38 org.springframework.beans.MutablePropertyValues
608 38 org.springframework.beans.factory.support.MethodOverrides
608 2 * ArrayKlassKlass
608 38 org.springframework.beans.factory.config.ConstructorArgumentValues
608 4 org.apache.xerces.impl.XMLDTDScannerImpl
576 24 java.util.Stack
576 36 java.util.regex.Pattern$Category
576 24 org.apache.naming.NamingEntry
560 7 java.net.URL[]
552 23 sun.management.MappedMXBeanType$BasicMXBeanType
552 1 java.util.Locale[]
552 22 java.io.ObjectStreamField[]
544 17 java.util.Collections$SynchronizedMap
176 11 java.util.regex.Pattern$Ctype
8 1 sun.reflect.GeneratedMethodAccessor49
8 1 sun.reflect.GeneratedMethodAccessor6
8 1 sun.reflect.GeneratedConstructorAccessor10
Heap traversal took 12.003 seconds.
- jinfo 的用法
可以輸出并修改運(yùn)行時(shí)的 java 進(jìn)程的 opts 。用處比較簡單,就是能輸出并修改運(yùn)行時(shí)的 java 進(jìn)程的運(yùn)行參數(shù)。用法是 jinfo -opt pid 如:查看 2788 的 MaxPerm 大小可以用 jinfo -flag MaxPermSize 2788 。
- jconsole 的用法
jconsole: 一個(gè) java GUI 監(jiān)視工具,可以以圖表化的形式顯示各種數(shù)據(jù)。并可通過遠(yuǎn)程連接監(jiān)視遠(yuǎn)程的服務(wù)器 VM 。
用 java 寫的 GUI 程序,用來監(jiān)控 VM ,并可監(jiān)控遠(yuǎn)程的 VM ,非常易用,而且功能非常強(qiáng)。命令行里打 jconsole ,選則進(jìn)程就可以了
不過我沒有運(yùn)行起來,老是報(bào)下面的錯(cuò)。會的朋友,幫忙看看。
[root@localhost bin]# jconsole
Exception in thread "AWT-EventQueue-0" java.awt.HeadlessException:
No X11 DISPLAY variable was set, but this program performed an operation which requires it. at java.awt.GraphicsEnvironment.checkHeadless(GraphicsEnvironment.java:159)
at java.awt.Window.<init>(Window.java:317)
at java.awt.Frame.<init>(Frame.java:419)
at javax.swing.JFrame.<init>(JFrame.java:194)
at sun.tools.jconsole.JConsole.<init>(JConsole.java:65)
at sun.tools.jconsole.JConsole$4.run(JConsole.java:666)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:461)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:163)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:157)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:149)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:110)
- jdb 的用法
用來對 core 文件和正在運(yùn)行的 Java 進(jìn)程進(jìn)行實(shí)時(shí)地調(diào)試,里面包含了豐富的命令幫助您進(jìn)行調(diào)試,它的功能和 Sun studio 里面所帶的 dbx 非常相似,但 jdb 是專門用來針對 Java 應(yīng)用程序的。
- jmap 的用法
打印出某個(gè) java 進(jìn)程(使用 pid )內(nèi)存內(nèi)的,所有 ‘ 對象 ’ 的情況(如:產(chǎn)生那些對象,及其數(shù)量)。
可以輸出所有內(nèi)存中對象的工具,甚至可以將 VM 中的 heap ,以二進(jìn)制輸出成文本。使用方法 jmap -histo pid 。如果連用 SHELL jmap -histo pid>a.log 可以將其保存到文本中去,在一段時(shí)間后,使用文本對比工具,可以對比出 GC 回收了哪些對象。 jmap -dump:format=b,file=String 3024 可以將 3024 進(jìn)程的內(nèi)存 heap 輸出出來到 String 文件里。
[root@localhost bin]# jmap -histo 25917
Attaching to process ID 26221, please wait...
Debugger attached successfully.
Client compiler detected.
JVM version is 1.5.0_08-b03
Iterating over heap. This may take a while...
Unknown oop at 0xaa6e42d0
Oop's klass is null
Object Histogram:
Size Count Class description
-------------------------------------------------------
3722768 30467 * ConstMethodKlass
1976480 25334 char[]
1907880 46994 * SymbolKlass
1762088 2947 byte[]
1709536 30467 * MethodKlass
1487816 2600 * ConstantPoolKlass
1009576 2600 * InstanceKlassKlass
904880 2199 * ConstantPoolCacheKlass
741432 30893 java.lang.String
653576 4785 int[]
351760 4397 java.lang.reflect.Method
277824 2894 java.lang.Class
248704 3401 short[]
200888 4411 java.lang.Object[]
193656 4045 java.lang.Object[]
179744 5617 java.util.TreeMap$Entry
175688 1800 java.util.HashMap$Entry[]
165288 6887 java.util.HashMap$Entry
104736 3273 java.lang.ref.SoftReference
104136 4339 java.lang.ref.WeakReference
96096 3521 java.lang.String[]
86160 3590 java.util.Hashtable$Entry
85584 3566 java.util.ArrayList
83472 1206 java.util.Hashtable$Entry[]
82944 1728 java.beans.MethodDescriptor
80560 265 * ObjArrayKlassKlass
69120 1728 java.util.HashMap
52464 3055 java.lang.Class[]
43040 1076 java.util.Hashtable
42496 664 org.apache.commons.modeler.AttributeInfo
37880 947 java.util.TreeMap
33896 557 javax.management.modelmbean.ModelMBeanAttributeInfo[]
33152 518 java.beans.PropertyDescriptor
616 11 org.springframework.aop.framework.ProxyFactory
608 19 java.util.PropertyPermission
608 38 org.springframework.beans.MutablePropertyValues
608 38 org.springframework.beans.factory.support.MethodOverrides
608 2 * ArrayKlassKlass
608 38 org.springframework.beans.factory.config.ConstructorArgumentValues
608 4 org.apache.xerces.impl.XMLDTDScannerImpl
576 24 java.util.Stack
576 36 java.util.regex.Pattern$Category
576 24 org.apache.naming.NamingEntry
560 7 java.net.URL[]
552 23 sun.management.MappedMXBeanType$BasicMXBeanType
552 1 java.util.Locale[]
552 22 java.io.ObjectStreamField[]
544 17 java.util.Collections$SynchronizedMap
176 11 java.util.regex.Pattern$Ctype
8 1 sun.reflect.GeneratedMethodAccessor49
8 1 sun.reflect.GeneratedMethodAccessor6
8 1 sun.reflect.GeneratedConstructorAccessor10
Heap traversal took 12.003 seconds.
- jinfo 的用法
可以輸出并修改運(yùn)行時(shí)的 java 進(jìn)程的 opts 。用處比較簡單,就是能輸出并修改運(yùn)行時(shí)的 java 進(jìn)程的運(yùn)行參數(shù)。用法是 jinfo -opt pid 如:查看 2788 的 MaxPerm 大小可以用 jinfo -flag MaxPermSize 2788 。
- jconsole 的用法
jconsole: 一個(gè) java GUI 監(jiān)視工具,可以以圖表化的形式顯示各種數(shù)據(jù)。并可通過遠(yuǎn)程連接監(jiān)視遠(yuǎn)程的服務(wù)器 VM 。
用 java 寫的 GUI 程序,用來監(jiān)控 VM ,并可監(jiān)控遠(yuǎn)程的 VM ,非常易用,而且功能非常強(qiáng)。命令行里打 jconsole ,選則進(jìn)程就可以了
不過我沒有運(yùn)行起來,老是報(bào)下面的錯(cuò)。會的朋友,幫忙看看。
[root@localhost bin]# jconsole
Exception in thread "AWT-EventQueue-0" java.awt.HeadlessException:
No X11 DISPLAY variable was set, but this program performed an operation which requires it. at java.awt.GraphicsEnvironment.checkHeadless(GraphicsEnvironment.java:159)
at java.awt.Window.<init>(Window.java:317)
at java.awt.Frame.<init>(Frame.java:419)
at javax.swing.JFrame.<init>(JFrame.java:194)
at sun.tools.jconsole.JConsole.<init>(JConsole.java:65)
at sun.tools.jconsole.JConsole$4.run(JConsole.java:666)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:461)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:163)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:157)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:149)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:110)
- jdb 的用法
用來對 core 文件和正在運(yùn)行的 Java 進(jìn)程進(jìn)行實(shí)時(shí)地調(diào)試,里面包含了豐富的命令幫助您進(jìn)行調(diào)試,它的功能和 Sun studio 里面所帶的 dbx 非常相似,但 jdb 是專門用來針對 Java 應(yīng)用程序的。
原文鏈接:http://blog.csdn.net/jacky0922/article/details/6201878
【編輯推薦】