一、jps命令
1. 介紹
jps(Java Virtual Machine Process Status Tool)工具用于顯示當(dāng)前系統(tǒng)的進(jìn)程情況,可以使用該命令查看當(dāng)前服務(wù)器的Java進(jìn)程,該工具比較簡單,我們來看下:
deploy@127.0.0.1:~$ jps -help
usage: jps [-help]
jps [-q] [-mlvV] [<hostid>]
Definitions:
<hostid>: <hostname>[:<port>]
我們來簡單看下它的命令格式:jps [參數(shù)] [hostid],其中參數(shù)為:
-q 僅顯示Java進(jìn)程id,不包含類名等其他信息
-m 輸出傳遞給main方法的參數(shù)
-l 輸出應(yīng)用程序main class的完整包名或者 應(yīng)用程序的jar文件完整路徑名
-v 輸出進(jìn)程所對應(yīng)的jvm參數(shù)
-V 輸出通過flag文件傳遞到JVM中的參數(shù)(.hotspotrc文件或-XX:Flags=所指定的文件
-Joption 傳遞參數(shù)到vm,例如:-J-Xms48m
而hostid格式為:
[protocol:][[//]hostname][:port][/servername]
2. 使用
接下來,我們來簡單看下它的使用。
1)首先,我們來看下該命令默認(rèn)情況下的展示及加上相關(guān)參數(shù)的展示:
deploy@127.0.0.1:~$ jps
27075 BootStrap
3875 App
29049 Jps
可以看到,只展示進(jìn)程名稱及進(jìn)程id,這里可以看到j(luò)ps命令也開了一個(gè)進(jìn)程,因?yàn)閖ps其實(shí)也是一個(gè)Java命令,也要占一個(gè)進(jìn)程的;然后使用jps -l:
deploy@127.0.0.1:~$ jps -l
27075 com.test.spring.boot.BootStrap
3875 com.test.log.App
29415 sun.tools.jps.Jps
展示進(jìn)程id及進(jìn)程對應(yīng)的完整的包名稱;
2)接下來使用jps -v:
deploy@127.0.0.1:~$ jps -v
27075 BootStrap -Xms5120m -Xmx5120m -Xmn2560m -XX:MaxMetaspaceSize=128m -XX:MetaspaceSize=128m -Dfile.encoding=UTF-8 -XX:+UseConcMarkSweepGC ...(省略)
3875 App -Dfile.encoding=UTF-8 -Xms128m -Xmx512m -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+UseCMSCompactAtFullCollection ...(省略)
29455 Jps -Denv.class.path=.:/usr/java/jdk1.8.0_66/lib/tools.jar:/usr/java/jdk1.8.0_66/lib/dt.jar -Dapplication.home=/usr/java/jdk1.8.0_66 -Xms8m
由于JVM展示的內(nèi)容比較多,所以這里就省略了。我們可以從這里看到JVM的一些配置參數(shù),并且可以看到JVM日志的輸出路徑,可以很方便的幫助我們定位問題。
3)接下來我們看下 jps -q和 jps -m:
deploy@127.0.0.1:~$ jps -q
29474
27075
3875
deploy@127.0.0.1:~$ jps -m
29601 Jps -m
27075 BootStrap /workspace/test/SprintTest/conf/test.json
3875 App /workspace/test/LogTest/conf/test.json
可以看到,-q命令只展示進(jìn)程號,而-m則是主方法的參數(shù)。
4)一般情況下,我們使用比較多的是jps -mlv參數(shù);
5)獲取元操服務(wù)器jps信息
jps命令是支持查看遠(yuǎn)程服務(wù)上的JVM進(jìn)程信息的,但如果要查看其他機(jī)器上的JVM進(jìn)程,需要在待查看機(jī)器上開啟 jstatd 服務(wù);
3. 原理
java程序在啟動(dòng)后,會在java.io.tmpdir指定的目錄下,就是臨時(shí)文件夾里,生成一個(gè)類似于hsperfdata_(userName)的文件夾(Linux中為/tmp/hsperfdata_{userName}/),該文件夾中有幾個(gè)文件,名字就是java進(jìn)程的pid;而jps命令列出當(dāng)前運(yùn)行的java進(jìn)程,就是把這個(gè)目錄里的文件名列一下而已。 至于系統(tǒng)的參數(shù)什么,可以通過解析這幾個(gè)文件獲得。
deploy@127.0.0.1:~$ cd /tmp/hsperfdata_deploy/
deploy@127.0.0.1:/tmp/hsperfdata_deploy$ ll
total 64
-rw------- 1 deploy deploy 32768 May 26 17:24 27075
-rw------- 1 deploy deploy 32768 May 26 17:24 3875
可以看到,進(jìn)程號就是上面我們所展示的。
4.注意事項(xiàng)
注意,jps僅查找當(dāng)前用戶的Java進(jìn)程,而不是當(dāng)前系統(tǒng)中的所有進(jìn)程,所以查詢的時(shí)候需要注意用戶的相關(guān)權(quán)限。
本文參考自(鏈接中包含了jps失效及更多有關(guān)jps的內(nèi)容,大家都可以進(jìn)行參考):
https://www.hollischuang.com/archives/105
Jps無法查看運(yùn)行程序進(jìn)程
二、jinfo命令
1. 介紹
??jinfo(Java Configuration Info),是Java自帶的命令,用于實(shí)時(shí)查看和調(diào)整Java應(yīng)用程序的配置參數(shù),其中配置參數(shù)包含兩部分,其中只能查看的是Java系統(tǒng)屬性,既能查看又能調(diào)整的是JVM參數(shù);并且,當(dāng)系統(tǒng)崩潰時(shí),jinfo可以從core文件里面知道崩潰的Java應(yīng)用程序的配置信息。
deploy@127.0.0.1:~$ jinfo -help
Usage:
jinfo [option] <pid>
(to connect to running process)
jinfo [option] <executable <core>
(to connect to a core file)
jinfo [option] [server_id@]<remote server IP or hostname>
(to connect to remote debug server)
where <option> is one of:
-flag <name> to print the value of the named VM flag
-flag [+|-]<name> to enable or disable the named VM flag
-flag <name>=<value> to set the named VM flag to the given value
-flags to print VM flags
-sysprops to print Java system properties
<no option> to print both of the above
-h | -help to print this help message
deploy@127.0.0.1:~$
我們來簡單看下它的操作格式:
jinfo [option] <pid> 進(jìn)程id
jinfo [option] <executable <core> 生成core dump文件
jinfo [option] [server_id@] ... 連接遠(yuǎn)程機(jī)器操作
其中,參數(shù)option我們可以直接看上面的注釋,比較簡單,這里簡單解釋下:
[option]
<no option> 默認(rèn)情況下,會展示全部的JVM參數(shù)和Java系統(tǒng)屬性
-flag <name> 查看對應(yīng)名稱的JVM參數(shù)
-flag [+|-]<name> 對布爾類型的JVM配置進(jìn)行開啟或關(guān)閉
-flag <name>=<value> 設(shè)置對應(yīng)的JVM配置
-flags 展示全部JVM參數(shù)
-sysprops 展示Java系統(tǒng)屬性
-h | -help 展示幫助信息
2. 使用
我們在服務(wù)器上進(jìn)行簡單操作下:
1)先看下最簡單的方式,jinfo pid:
deploy@127.0.0.1:~$ jinfo 20995
Attaching to process ID 20995, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.66-b17
Java System Properties:
com.sun.management.jmxremote.authenticate = false
java.runtime.name = Java(TM) SE Runtime Environment
java.vm.version = 25.66-b17
sun.boot.library.path = /usr/java/jdk1.8.0_66/jre/lib/amd64
java.vendor.url = http://java.oracle.com/
java.vm.vendor = Oracle Corporation
path.separator = :
java.rmi.server.randomIDs = true
file.encoding.pkg = sun.io
java.vm.name = Java HotSpot(TM) 64-Bit Server VM
sun.os.patch.level = unknown
sun.java.launcher = SUN_STANDARD
user.country = US
...
VM Flags:
Non-default VM flags: -XX:CICompilerCount=4 -XX:CMSFullGCsBeforeCompaction=0
-XX:CMSInitiatingOccupancyFraction=62 -XX:CMSTriggerRatio=70
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=null
-XX:InitialHeapSize=536870912 -XX:+ManagementServer
-XX:MaxHeapSize=536870912 -XX:MaxMetaspaceSize=67108864
...
Command line: -Xms512m -Xmx512m -Xmn256m -XX:MaxMetaspaceSize=64m
-XX:MetaspaceSize=64m -Dfile.encoding=UTF-8 -XX:+UseConcMarkSweepGC
-XX:+UseParNewGC -XX:+UseCMSCompactAtFullCollection
-XX:CMSFullGCsBeforeCompaction=0 -XX:CMSInitiatingOccupancyFraction=62
-XX:CMSTriggerRatio=70
...
這里展示的信息太多,省略了大部分?jǐn)?shù)據(jù);不過可以看到,展示的數(shù)據(jù)總體上是分兩部分的,一部分是Java System Properties:,另一部分是VM Flags:,
2)接下來我們看下 展示指定的JVM參數(shù)的值:
deploy@127.0.0.1:~$ jinfo -flag MaxNewSize 20995
-XX:MaxNewSize=268435456
3)JVM參數(shù)的調(diào)整,如果是布爾類型的,使用 jinfo -flag [+|-]<name> PID,其中 + 表示開啟,- 表示關(guān)閉操作;而如果是字符串或者數(shù)字類型,使用 jinfo -flag <name>=<value>,這里就不多演示了;
4)jinfo雖然可以在java程序運(yùn)行時(shí)動(dòng)態(tài)地修改JVM參數(shù),但并不是所有的參數(shù)都支持動(dòng)態(tài)修改,而哪些參數(shù)支持jinfo動(dòng)態(tài)修改呢?在官方文檔中有一段這樣的描述:
Flags marked as manageable are dynamically writeable through the JDK management interface (com.sun.management.HotSpotDiagnosticMXBean API) and also through JConsole.
也就是說,通過com.sun.management.HotSpotDiagnosticMXBean 這個(gè)類的接口得到的參數(shù),或者是標(biāo)記為manageable的參數(shù)菜可以支持動(dòng)態(tài)修改。首先,我們來看下標(biāo)記為manageable的Flags,我們可以通過如下命令查看:
Linux環(huán)境: java -XX:+PrintFlagsInitial | grep manageable
Window環(huán)境:java -XX:+PrintFlagsInitial | findstr manageable
運(yùn)行后獲取到的數(shù)據(jù)如下:
deploy@127.0.0.1:~$ java -XX:+PrintFlagsInitial | grep manageable
intx CMSAbortablePrecleanWaitMillis = 100 {manageable}
intx CMSTriggerInterval = -1 {manageable}
intx CMSWaitDuration = 2000 {manageable}
bool HeapDumpAfterFullGC = false {manageable}
bool HeapDumpBeforeFullGC = false {manageable}
bool HeapDumpOnOutOfMemoryError = false {manageable}
ccstr HeapDumpPath = {manageable}
uintx MaxHeapFreeRatio = 70 {manageable}
uintx MinHeapFreeRatio = 40 {manageable}
bool PrintClassHistogram = false {manageable}
bool PrintClassHistogramAfterFullGC = false {manageable}
bool PrintClassHistogramBeforeFullGC = false {manageable}
bool PrintConcurrentLocks = false {manageable}
bool PrintGC = false {manageable}
bool PrintGCDateStamps = false {manageable}
bool PrintGCDetails = false {manageable}
bool PrintGCID = false {manageable}
bool PrintGCTimeStamps = false {manageable}
deploy@127.0.0.1:~$
備注:為了展示,格式做了簡單調(diào)整。
另外,我們也可以通過代碼來實(shí)現(xiàn),方式是通過 通過HotSpotDiagnosticMXBean API,查看該類的 Java Doc,有一個(gè)getDiagnosticOptions()這樣的方法,該方法的詳細(xì)描述如下:
Returns a list of VMOption objects for all diagnostic options. A diagnostic option is a writeable VM option that can be set dynamically mainly for troubleshooting and diagnosis.
接下來通過Java代碼調(diào)用該API得到所有可動(dòng)態(tài)修改的JVM參數(shù), java代碼如下:
/**
* @author afei
* @version 1.0.0
* @since 2017年07月25日
*/
public class DiagnosticOptionsTest {
public static void main(String[] args) {
HotSpotDiagnostic mxBean = new HotSpotDiagnostic();
List<VMOption> diagnosticVMOptions = mxBean.getDiagnosticOptions();
for (VMOption vmOption:diagnosticVMOptions){
System.out.println(vmOption.getName() + " = " + vmOption.getValue());
}
}
}
結(jié)果的話,大家跑一下程序就知道了,可以看到和Linux命令操作是一樣的結(jié)果。
備注:由于HotSpotDiagnosticMXBean 是接口(public class HotSpotDiagnostic implements HotSpotDiagnosticMXBean ),所以需要通過它唯一的實(shí)現(xiàn)類HotSpotDiagnostic 來調(diào)用這個(gè)方法。
3. 總結(jié)
jinfo命令比較簡單,使用該命令可以讓我們在不重啟JVM的情況下動(dòng)態(tài)的修改JVM的參數(shù),這點(diǎn)對我們來說有時(shí)候有些時(shí)候還是挺有用的。
本文最后部分來自阿飛哥的博客,博客地址:
阿飛的博客 - 簡書 - jinfo命令詳解