主要是介紹一下對運行Java程序的一些跟蹤,以及對JVM內存等方面進行運維的一些方法。java
用於獲取全部的JVM進程信息,相似於linux的ps命令linux
//輸出進程號與執行的主類名(jar包名)
jps -l
結果以下:
30352
20708 sun.tools.jps.Jps
6876 mtex-config-0.0.1-SNAPSHOT.jar
複製代碼
用於監控java進程內部各種運行狀態信息的工具,能夠監控本地或遠程虛擬機類裝載、內存、垃圾回收等信息。spring
//監控GC狀況 間隔1000毫秒執行1次 執行5次
jstat -gc 6876 1000 5
執行結果以下:
C:\Users\dell>jstat -gc 6876 1000 5
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
13824.0 15872.0 13804.6 0.0 140288.0 129170.6 102400.0 19730.9 54528.0 52078.9 7168.0 6684.3 10 0.143 2 0.172 0.315
13824.0 15872.0 13804.6 0.0 140288.0 129170.6 102400.0 19730.9 54528.0 52078.9 7168.0 6684.3 10 0.143 2 0.172 0.315
13824.0 15872.0 13804.6 0.0 140288.0 129170.6 102400.0 19730.9 54528.0 52078.9 7168.0 6684.3 10 0.143 2 0.172 0.315
13824.0 15872.0 13804.6 0.0 140288.0 129170.6 102400.0 19730.9 54528.0 52078.9 7168.0 6684.3 10 0.143 2 0.172 0.315
13824.0 15872.0 13804.6 0.0 140288.0 129170.6 102400.0 19730.9 54528.0 52078.9 7168.0 6684.3 10 0.143 2 0.172 0.315
結果說明:
S0C 年輕代s0區容量
S1C 年輕代s1區容量
S0U 年輕代s0區使用量
S1U 年輕代s1區使用量
EC 年輕代eden區容量
EU 年輕代eden區容量
OC 老年代容量
OU 老年代使用量
MC 元空間容量
MU 元空間使用量
CCSC 壓縮類空間容量
CCSU 壓縮類空間使用大小
YGC 從應用程序啓動到採樣時年輕代中gc次數
YGCT 從應用程序啓動到採樣時年輕代中gc時間
FGC 從應用程序啓動到採樣時全gc次數
FGCT 從應用程序啓動到採樣時全gc時間
GCT 從應用程序啓動到採樣時gc用的總時間(s)
複製代碼
s0和s1中必然有一個的使用空間爲0,用於複製交換apache
JDK 1.8如下MC/MU指標爲PC/PU。(jdk1.8使用元空間替換了永久代)tomcat
經過參數的不一樣,能夠進行某些方面的重點信息關注bash
選項 | 做用 |
---|---|
-class | 監視類裝載、卸載數量、總空間以及類裝載所耗費的時間 |
-gc | 監視Java堆情況,包括Eden區、兩個survivor區、老年代、元空間的容量、已用空間、GC時間合計等信息 |
-gccapacity | 監視內容與-gc基本相同,但輸出主要關注Java堆各個區域使用到的最大、最小空間 |
-gcutil | 監視內容與-gc基本相同,但輸出主要關注已使用空間佔總空間的百分比 |
-gccause | 與-gcutil功能同樣,可是會額外輸出致使上一次GC產生的緣由 |
-gcnew | 監視新生代GC情況 |
-gcnewcapacity | 監視內容與-gcnew基本相同,輸出主要關注使用到的最大、最小空間 |
-gcold | 監視老年代情況 |
-gcoldcapacity | 監視內容與-gcold基本相同,輸出主要關注用到的最大、最小空間 |
-gcmetacapacity | 輸出元數據用到的最大、最小空間 |
-compiler | 輸出JIT編譯器編譯過的方法、耗時等信息 |
-printcompilation | 輸出已經被JIT編譯的方法 |
能夠用來查詢堆中的實例或者進行堆dump等。app
//顯示堆中對象統計信息,包括類、實例數、合計佔用量
jmap -histo 6876 > a.txt
num #instances #bytes class name
----------------------------------------------
1: 652896 67501960 [B
2: 493614 47624832 [C
3: 54335 17164304 [I
4: 126862 3044688 java.lang.String
5: 28292 2489696 java.lang.reflect.Method
6: 27951 1786648 [Ljava.lang.Object;
7: 21992 1334608 [Lorg.springframework.boot.context.properties.source.ConfigurationPropertyName$ElementType;
8: 18122 1311816 [Ljava.util.HashMap$Node;
9: 32653 1306120 java.util.LinkedHashMap$Entry
10: 10985 1219992 java.lang.Class
11: 35321 1130272 java.util.concurrent.ConcurrentHashMap$Node
12: 17251 966056 java.util.LinkedHashMap
13: 29707 950624 java.util.HashMap$Node
14: 45305 908512 [Ljava.lang.Class;
15: 512 724368 [Ljava.util.concurrent.ConcurrentHashMap$Node;
16: 13340 640320 java.util.HashMap
17: 7763 604160 [S
18: 7641 550152 java.lang.reflect.Field
...
複製代碼
執行此命令須要將輸出重定向到文件裏,不然會有幾千上萬行運維
//生成堆快照信息
jmap -dump:format=b,file=heap.hprof 6876
複製代碼
用於生成java的線程快照信息eclipse
jstack -l 6876 > threadDump.txt
執行結果:
2020-03-23 16:51:55
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.65-b01 mixed mode):
"DestroyJavaVM" #58 prio=5 os_prio=0 tid=0x0000000060c4a000 nid=0x6618 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"http-nio-8601-Acceptor" #32 daemon prio=5 os_prio=0 tid=0x0000000060c49800 nid=0x824 runnable [0x00000000648de000]
java.lang.Thread.State: RUNNABLE
at sun.nio.ch.ServerSocketChannelImpl.accept0(Native Method)
at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:422)
at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:250)
- locked <0x00000000e0c3b670> (a java.lang.Object)
at org.apache.tomcat.util.net.NioEndpoint.serverSocketAccept(NioEndpoint.java:463)
at org.apache.tomcat.util.net.NioEndpoint.serverSocketAccept(NioEndpoint.java:73)
at org.apache.tomcat.util.net.Acceptor.run(Acceptor.java:95)
at java.lang.Thread.run(Thread.java:745)
...
複製代碼
此命令也最好能夠重定向到文件,輸出結果較多工具
VisualVM是目前爲止JDK發佈功能最強大的運行監控故障處理程序。
在jdk路徑的bin目錄下,jvisualvm.exe
雙擊工具,進入主界面,左側便可看到本地的java進程,雙擊便可在右側查看內容。
執行java -jar啓動命令時候加入如下參數,hostname爲遠程的主機名,port使用一個沒被佔用的端口
-Djava.rmi.server.hostname=xxxxxx -Dcom.sun.management.jmxremote.port=1099 -Dcom.sun.management.jmxremote=true -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.managementote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false
複製代碼
雙擊左側遠程,添加主機IP,遠程下會出現對應的主機,雙擊選擇添加JMX鏈接,彈框輸入端口。點擊肯定,便可進行遠程監控。
一、安裝
eclipse -->help --> eclipse marketplace,輸入memory,搜索出具體的插件,進行安裝。
二、使用
使用jmap命令或者經過vusal工具dump下內存快照,拖進eclipse便可。
參數名稱 | 含義 | 默認值 |
---|---|---|
-Xms | 初始堆大小 | 物理內存的1/64 |
-Xmx | 最大堆大小 | 物理內存的1/4 |
-XX:NewSize | 年輕代的初始大小 | |
-XX:MaxNewSize | 年輕代的最大值 | |
-Xmn | 年輕代的大小,若是經過-Xmn來配置新生代的內存大小,那麼-XX:newSize = -XX:MaxNewSize = -Xmn | |
-XX:NewRatio | 年輕代與老年代的比例 4 表示 年輕代與老年代比例爲 1:4 | |
-XX:SurvivorRatio | 兩個Survivor區與eden的比例 8 表示兩個survivor:eden爲 2:8 |
查看本機默認參數命令
java -XX:+PrintFlagsFinal > E:\ab.txt
複製代碼
示例:
一、找到java的進程
C:\Users\dell>jps -l
24352 cn.mastercom.MtexConfigApplication
30352
43508 sun.tools.jps.Jps
複製代碼
二、對具體進程進行線程dump
C:\Users\dell\Desktop>jstack -l 24352 > thread.txt
複製代碼
三、使用工具查看佔用高的線程ID
linux經過top 命令進程查詢
top -H -p 24352
top - 16:44:36 up 74 days, 1:22, 1 user, load average: 0.52, 0.39, 0.39
Threads: 30 total, 0 running, 30 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.3 us, 0.3 sy, 0.0 ni, 99.0 id, 0.3 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 1882752 total, 92228 free, 980456 used, 810068 buff/cache
KiB Swap: 0 total, 0 free, 0 used. 706556 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
17063 root 20 0 2525764 138224 12788 S 0.0 7.3 0:00.00 java
17065 root 20 0 2525764 138224 12788 S 0.0 7.3 0:02.62 java
17067 root 20 0 2525764 138224 12788 S 0.0 7.3 0:05.73 java
17068 root 20 0 2525764 138224 12788 S 0.0 7.3 0:00.00 java
17069 root 20 0 2525764 138224 12788 S 0.0 7.3 0:00.00 java
17070 root 20 0 2525764 138224 12788 S 0.0 7.3 0:00.00 java
17071 root 20 0 2525764 138224 12788 S 0.0 7.3 0:07.06 java
17072 root 20 0 2525764 138224 12788 S 0.0 7.3 0:01.59 java
17073 root 20 0 2525764 138224 12788 S 0.0 7.3 0:00.00 java
能夠看到CPU佔用高的百分比
複製代碼
windwos能夠使用ProcessExplorer軟件進行查看
四、將線程ID轉爲16進制,由於線程dump的線程ID是使用16進制的。
43404 --> A98C
複製代碼
五、去以前dump的線程映像中查看對應線程
"Catalina-utility-1" #17 prio=1 os_prio=-2 tid=0x000000006130b000 nid=0xa98c waiting on condition [0x000000005e7be000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000e358e9a0> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1088)
at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
Locked ownable synchronizers:
- None
複製代碼
若是是本身寫的代碼,能夠從上面查看到具體的問題。