JAVA系統(tǒng)定位常用命令
遇到產(chǎn)品環(huán)境緊急問題,這是系統(tǒng)上線不可避免的事情。一般來說,需要抓取兩個方面的數(shù)據(jù):
- 操作系統(tǒng)相關數(shù)據(jù);
- Java運行相關數(shù)據(jù)
本文列出相關的常用命令。
命令列表
操作系統(tǒng)
遇到線上問題,首先查看操作系統(tǒng)相關數(shù)據(jù)。
free
[deploy@perf-jesse-01w logs]$ free -m
total used free shared buffers cached
Mem: 2006 1990 15 0 24 476
-/+ buffers/cache: 1489 517
Swap: 1023 165 858
'free -m' 表示為M為單元查看內(nèi)存使用情況。重點關注free, cached列。 可以看出系統(tǒng)的總共2G內(nèi)存,buffer cache使用24M, page cached占用476M, 系統(tǒng)應用可使用內(nèi)存517M。Swap空間使用165M,剩下858M。
根據(jù)經(jīng)驗,M=應用程序可使用內(nèi)存/總物理內(nèi)存,如果M > 70%表示內(nèi)存充足;20% < M < 70%, 表示內(nèi)存可用;M < 20%, 表示內(nèi)存緊張??梢钥闯?,上面的應用內(nèi)存緊張。
vmstat
[deploy@perf-jesse-01w logs]$ vmstat 2 1
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
1 0 169708 16228 26564 488576 0 0 13 3 0 1 1 0 99 0 0
- proc
- r 表示等待cpu表的進程數(shù)
- b 表示等待資源的進程數(shù)
- memory
- swpd 表示切換到內(nèi)存交換區(qū)的數(shù)量
- free 表示空閑的物理內(nèi)存數(shù)量
- buff 表示buffers cache的內(nèi)存數(shù)量
- cached 表示page cache的內(nèi)存數(shù)量,如果該值越大,說明cache到內(nèi)存中文件越多
- swap
-si 由內(nèi)存進入內(nèi)存交換區(qū)的數(shù)量
-so 由內(nèi)存交換區(qū)進入內(nèi)存的數(shù)量 - io
- bi 讀磁盤(kb/s)
- bo 寫磁盤(kb/s)
一般經(jīng)驗,bi + bo參考值為1000,如果超過1000,且wa比較大說明磁盤I/O有問題。
- system
- in 每秒設備中斷數(shù)
- cs 每秒上下文切換數(shù)
- cpu
- us 用戶進程消耗CPU時間比
- uy 內(nèi)核進程消耗CPU時間比
一般經(jīng)驗,如果us + uy > 80%, 則說明CPU緊張
iostat
ping
$ ping www.sina.com.cn
PING spool.grid.sinaedge.com (218.30.66.248): 56 data bytes
64 bytes from 218.30.66.248: icmp_seq=0 ttl=55 time=18.282 ms
64 bytes from 218.30.66.248: icmp_seq=1 ttl=55 time=18.430 ms
64 bytes from 218.30.66.248: icmp_seq=2 ttl=55 time=19.967 ms
JAVA運行
查看JVM相關數(shù)據(jù)。
jstack
Jesse-4:~$ jstack -l 11745
2017-12-09 20:33:01
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.31-b07 mixed mode):
"Attach Listener" #18 daemon prio=9 os_prio=31 tid=0x00007fc66c81d800 nid=0x4107 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"Timer-0" #16 prio=5 os_prio=31 tid=0x00007fc66dfc8000 nid=0x6903 in Object.wait() [0x000000011de3e000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000007ab0fa120> (a java.util.TaskQueue)
at java.lang.Object.wait(Object.java:502)
at java.util.TimerThread.mainLoop(Timer.java:526)
- locked <0x00000007ab0fa120> (a java.util.TaskQueue)
at java.util.TimerThread.run(Timer.java:505)
Locked ownable synchronizers:
- None
"GC Daemon" #15 daemon prio=2 os_prio=31 tid=0x00007fc66aa19800 nid=0x6703 in Object.wait() [0x000000011d810000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000007aafbc188> (a sun.misc.GC$LatencyLock)
at sun.misc.GC$Daemon.run(GC.java:117)
- locked <0x00000007aafbc188> (a sun.misc.GC$LatencyLock)
Locked ownable synchronizers:
- None
"RMI TCP Accept-0" #14 daemon prio=5 os_prio=31 tid=0x00007fc669219000 nid=0x6303 runnable [0x000000011ca84000]
java.lang.Thread.State: RUNNABLE
at java.net.PlainSocketImpl.socketAccept(Native Method)
at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:404)
at java.net.ServerSocket.implAccept(ServerSocket.java:545)
at java.net.ServerSocket.accept(ServerSocket.java:513)
at sun.management.jmxremote.LocalRMIServerSocketFactory$1.accept(LocalRMIServerSocketFactory.java:52)
at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.executeAcceptLoop(TCPTransport.java:400)
at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.run(TCPTransport.java:372)
at java.lang.Thread.run(Thread.java:745)
Locked ownable synchronizers:
- None
"RMI TCP Accept-9430" #13 daemon prio=5 os_prio=31 tid=0x00007fc66a320800 nid=0x6103 runnable [0x000000011c981000]
java.lang.Thread.State: RUNNABLE
at java.net.PlainSocketImpl.socketAccept(Native Method)
at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:404)
at java.net.ServerSocket.implAccept(ServerSocket.java:545)
at java.net.ServerSocket.accept(ServerSocket.java:513)
at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.executeAcceptLoop(TCPTransport.java:400)
at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.run(TCPTransport.java:372)
at java.lang.Thread.run(Thread.java:745)
Locked ownable synchronizers:
- None
"RMI TCP Accept-0" #12 daemon prio=5 os_prio=31 tid=0x00007fc66a320000 nid=0x6007 runnable [0x000000011c87e000]
java.lang.Thread.State: RUNNABLE
at java.net.PlainSocketImpl.socketAccept(Native Method)
at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:404)
at java.net.ServerSocket.implAccept(ServerSocket.java:545)
at java.net.ServerSocket.accept(ServerSocket.java:513)
at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.executeAcceptLoop(TCPTransport.java:400)
at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.run(TCPTransport.java:372)
at java.lang.Thread.run(Thread.java:745)
Locked ownable synchronizers:
- None
"Service Thread" #10 daemon prio=9 os_prio=31 tid=0x00007fc66a034000 nid=0x5903 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
我們使用jstack來查看應用系統(tǒng)線程相關數(shù)據(jù), 如果線程發(fā)送死鎖,通過該命令產(chǎn)生的數(shù)據(jù)可以觀察到。
jmap
jmap -dump:format=b,file=/tmp/heap.hprof $pid
使用該命令獲取dump文件
jstat
[deploy@perf-jesse-01w tmp]$ /usr/java/default/bin/jstat -gccause 18912
S0 S1 E O P YGC YGCT FGC FGCT GCT LGCC GCC
0.00 50.00 58.22 88.69 67.44 39692 74.373 10 11.770 86.143 unknown GCCause No GC
-YGC minor gc次數(shù)
-YGCT minor gc耗時
-FGC full gc次數(shù)
-FGCT full gc耗時
jinfo
Jesse-4:tools$ jinfo 11745
Attaching to process ID 11745, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.31-b07
Java System Properties:
java.vendor = Oracle Corporation
sun.java.launcher = SUN_STANDARD
etty.maxThreads = 200
java.vm.specification.vendor = Oracle Corporation
java.runtime.version = 1.8.0_31-b13
輸出java運行時的環(huán)境變量和JVM參數(shù)