常做Java開發(fā)的朋友,不管是做純后端開發(fā),還是做Java Web開發(fā),有一些操作你一定會經(jīng)常遇到。比如:
列出當(dāng)前系統(tǒng)上運(yùn)行了哪些Java應(yīng)用
這些應(yīng)用的部署路徑是什 么
某個(gè)Java應(yīng)用的堆內(nèi)存使用情況等
遇到類似的情況,你一般是怎么解決的?
我在工作中見過許多人,想要查看當(dāng)前正在運(yùn)行的Java應(yīng)用時(shí),會通過進(jìn)程管理器(Windows下),或者使用
ps -ef | grep java (在Linux下使用命令行)。通過這些來獲取運(yùn)行的Java應(yīng)用列表,以及對應(yīng)的PID(進(jìn)程ID)。
而查看堆內(nèi)存,可能會下載一些第三方的工具等。
其實(shí),JDK中已經(jīng)默認(rèn)自帶了一些小工具,非常好用,使用方便快捷。不信你看下面這些:
jps (Java Virtual Mathine Process Status Tool)
從名稱可以看出個(gè)大概。主要是把Java進(jìn)程的狀態(tài)列出來。
這個(gè)命令可以指定hostid,從而列出遠(yuǎn)程主機(jī)的Java進(jìn)程。
這個(gè)命令有幾個(gè)參數(shù),我比較常用的有
-l 輸出應(yīng)用程序主類的完整包名,或者是應(yīng)用程序JAR文件的完整路徑。
-v 輸出傳給JVM的參數(shù)。
一般通過jps -lv就可以把本地的所有Java進(jìn)程,以及傳給JVM的參數(shù),運(yùn)行的文件位置都列出來。這樣,一個(gè)命令上面前兩個(gè)問題就解決了。
2. jinfo (Java Configuration Info)
主要用來查看Java進(jìn)程使用的一些配置參數(shù),比如設(shè)置的堆內(nèi)存有多大,是否允許在OOM產(chǎn)生的時(shí)候dump出堆信息等。
除此之外,該命令還可以動態(tài)更改配置的項(xiàng),比如上面提到的OOM dump這個(gè)開關(guān)是關(guān)著的,那可以在運(yùn)行的時(shí)候再打開它。
3. jstate (Java Virtual Machine Statistics Monitoring Tool)
這個(gè)命令選項(xiàng)很多,根據(jù)不同的選項(xiàng),可以統(tǒng)計(jì)你感興趣的不同的數(shù)據(jù),比如你對JVM的垃圾回收數(shù)據(jù)感興趣,可以直接通過指定 -gc 來查看,而更常用的一個(gè)選項(xiàng)是 -gcutil 可以統(tǒng)計(jì)新生代,老年代垃圾收集的情況。
當(dāng)然,JDK自帶的小工具還有很多,以上面這幾個(gè)工具為例,其中后兩者在執(zhí)行時(shí),都需要先知道JVM的PID之后,才能執(zhí)行,畢竟這些工具需要了解你要查看哪個(gè)JVM。
下面我們來簡要了解下jps的大概實(shí)現(xiàn)原理。
每個(gè)JVM在啟動后,其本質(zhì)上依然是操作系統(tǒng)的一個(gè)進(jìn)程,都會存在一個(gè)PID值與之對應(yīng)。而JVM內(nèi)部的實(shí)現(xiàn),則是在每次啟動之后,在本地的一個(gè)目錄內(nèi)創(chuàng)建一個(gè)以當(dāng)前JVM的PID為文件名的文件,文件路徑和操作系統(tǒng)有關(guān),我的windows7下路徑是
C:\Users{這里是你的用戶名}\AppData\Local\Temp\hsperfdata_{這個(gè)也是你的用戶名}
在這個(gè)目錄下,所有你下在運(yùn)行的JVM對應(yīng)的PID文件都在這里了。下圖是我的列表
同樣的道理,如果你曾經(jīng)用過JConsole(這也是個(gè)JDK自帶的小工具),可能馬上就有感覺了。因?yàn)樗彩峭ㄟ^讀這個(gè)目錄下的文件信息得到需要的數(shù)據(jù),你看下面這個(gè)Jconsole新建連接的圖,這些PID剛好這上面的文件對應(yīng)是不是。
PS: 這些原理,我是通過看OpenJDK源碼了解到的,如果大家感興趣,可以一起交流。