ava性能調(diào)試命令
創(chuàng)新互聯(lián)從2013年開始,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務公司,擁有項目成都做網(wǎng)站、網(wǎng)站建設(shè)網(wǎng)站策劃,項目實施與項目整合能力。我們以讓每一個夢想脫穎而出為使命,1280元開化做網(wǎng)站,已為上家服務,為開化各地企業(yè)和個人服務,聯(lián)系電話:18980820575
java性能調(diào)試命令_性能測試--十個命令迅速發(fā)現(xiàn)性能問題
投機啟示錄
原創(chuàng)
關(guān)注
0點贊·85人閱讀
十個命令迅速發(fā)現(xiàn)性能問題
uptime
dmesg | tail
vmstat 1
mpstat -P ALL 1
pidstat 1
iostat -xz 1
free -m
sar -n DEV 1
sar -n TCP,ETCP 1
top
1. uptime
$ uptime
23:51:26 up 21:31, 1 user, load average: 30.02, 26.43, 19.02
這是一種用來快速查看系統(tǒng)平均負載的方法,它表明了系統(tǒng)中有多少要運行的任務(進程)。在 Linux 系統(tǒng)中,這些數(shù)字包含了需要在 CPU 中運行的進程以及正在等待 I/O(通常是磁盤 I/O)的進程。它僅僅是對系統(tǒng)負載的一個粗略展示,稍微看下即可。你還需要其他工具來進一步了解具體情況。
這三個數(shù)字展示的是一分鐘、五分鐘和十五分鐘內(nèi)系統(tǒng)的負載總量平均值按照指數(shù)比例壓縮得到的結(jié)果。從中我們可以看到系統(tǒng)的負載是如何隨時間變化的。比方你在檢查一個問題,然后看到 1 分鐘對應的值遠小于 15 分鐘的值,那么可能說明這個問題已經(jīng)過去了,你沒能及時觀察到。
在上面這個例子中,系統(tǒng)負載在隨著時間增加,因為最近一分鐘的負載值超過了 30,而 15 分鐘的平均負載則只有 19。這樣顯著的差距包含了很多含義,比方 CPU 負載。若要進一步確認的話,則要運行 vmstat 或 mpstat 命令。
2. dmesg | tail
$ dmesg | tail
[1880957.563150] perl invoked oom-killer: gfp_mask=0x280da, order=0, oom_score_adj=0
[...]
[1880957.563400] Out of memory: Kill process 18694 (perl) score 246 or sacrifice child
[1880957.563408] Killed process 18694 (perl) total-vm:1972392kB, anon-rss:1953348kB, file-rss:0kB
[2320864.954447] TCP: Possible SYN flooding on port 7001. Dropping request. Check SNMP counters.
這條命令顯式了最近的 10 條系統(tǒng)消息,如果它們存在的話。查找能夠?qū)е滦阅軉栴}的錯誤。上面的例子包含了 oom-killer,以及 TCP 丟棄一個請求。
千萬不要錯過這一步!dmesg 命令永遠值得一試
3. vmstat 1
$ vmstat 1
procs ---------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
34 0 0 200889792 73708 591828 0 0 0 5 6 10 96 1 3 0 0
32 0 0 200889920 73708 591860 0 0 0 592 13284 4282 98 1 1 0 0
32 0 0 200890112 73708 591860 0 0 0 0 9501 2154 99 1 0 0 0
32 0 0 200889568 73712 591856 0 0 0 48 11900 2459 99 0 0 0 0
32 0 0 200890208 73712 591860 0 0 0 0 15898 4840 98 1 1 0 0
vmstat(8) 是虛擬內(nèi)存統(tǒng)計的簡稱,其是一個常用工具(幾十年前為了 BSD 所創(chuàng)建)。其在每行打印一條關(guān)鍵的服務器的統(tǒng)計摘要。
vmstat 命令指定一個參數(shù) 1 運行,來打印每一秒的統(tǒng)計摘要。(這個版本的 vmstat)輸出的第一行的那些列,顯式的是開機以來的平均值,而不是前一秒的值?,F(xiàn)在,我們跳過第一行,除非你想要了解并記住每一列。
檢查這些列:
r:CPU 中正在運行和等待運行的進程的數(shù)量。其提供了一個比平均負載更好的信號來確定 CPU 是否飽和,因為其不包含 I/O。解釋:“r”的值大于了 CPU 的數(shù)量就表示已經(jīng)飽和了。
free:以 kb 為單位顯式的空閑內(nèi)存。如果數(shù)字位數(shù)很多,說明你有足夠的空閑內(nèi)存?!癴ree -m” 命令,是下面的第七個命令,其可以更好的說明空閑內(nèi)存的狀態(tài)。
si, so:Swap-ins 和 swap-outs。如果它們不是零,則代表你的內(nèi)存不足了。
us, sy, id, wa, st:這些都是平均了所有 CPU 的 CPU 分解時間。它們分別是用戶時間(user)、系統(tǒng)時間(內(nèi)核)(system)、空閑(idle)、等待 I/O(wait)、以及占用時間(stolen)(被其他訪客,或使用 Xen,訪客自己獨立的驅(qū)動域)。
CPU 分解時間將會通過用戶時間加系統(tǒng)時間確認 CPU 是否為忙碌狀態(tài)。等待 I/O 的時間一直不變則表明了一個磁盤瓶頸;這就是 CPU 的閑置,因為任務都阻塞在等待掛起磁盤 I/O 上了。你可以把等待 I/O 當成是 CPU 閑置的另一種形式,其給出了為什么 CPU 閑置的一個線索。
對于 I/O 處理來說,系統(tǒng)時間是很重要的。一個高于 20% 的平均系統(tǒng)時間,可以值得進一步的探討:也許內(nèi)核在處理 I/O 時效率太低了。
在上面的例子中,CPU 時間幾乎完全花在了用戶級,表明應用程序占用了太多 CPU 時間。而 CPU 的平均使用率也在 90% 以上。這不一定是一個問題;檢查一下“r”列中的飽和度。
4. mpstat -P ALL 1
$ mpstat -P ALL 1
Linux 3.13.0-49-generic (titanclusters-xxxxx) 07/14/2015 _x86_64_ (32 CPU)
07:38:49 PM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
07:38:50 PM all 98.47 0.00 0.75 0.00 0.00 0.00 0.00 0.00 0.00 0.78
07:38:50 PM 0 96.04 0.00 2.97 0.00 0.00 0.00 0.00 0.00 0.00 0.99
07:38:50 PM 1 97.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 2.00
07:38:50 PM 2 98.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00
07:38:50 PM 3 96.97 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 3.03
[...]
這個命令打印每個 CPU 的 CPU 分解時間,其可用于對一個不均衡的使用情況進行檢查。一個單獨 CPU 很忙碌則代表了正在運行一個單線程的應用程序。
5. pidstat 1
$ pidstat 1
Linux 3.13.0-49-generic (titanclusters-xxxxx) 07/14/2015 _x86_64_ (32 CPU)
07:41:02 PM UID PID %usr %system %guest %CPU CPU Command
07:41:03 PM 0 9 0.00 0.94 0.00 0.94 1 rcuos/0
07:41:03 PM 0 4214 5.66 5.66 0.00 11.32 15 mesos-slave
07:41:03 PM 0 4354 0.94 0.94 0.00 1.89 8 java
07:41:03 PM 0 6521 1596.23 1.89 0.00 1598.11 27 java
07:41:03 PM 0 6564 1571.70 7.55 0.00 1579.25 28 java
07:41:03 PM 60004 60154 0.94 4.72 0.00 5.66 9 pidstat
07:41:03 PM UID PID %usr %system %guest %CPU CPU Command
07:41:04 PM 0 4214 6.00 2.00 0.00 8.00 15 mesos-slave
07:41:04 PM 0 6521 1590.00 1.00 0.00 1591.00 27 java
07:41:04 PM 0 6564 1573.00 10.00 0.00 1583.00 28 java
07:41:04 PM 108 6718 1.00 0.00 0.00 1.00 0 snmp-pass
07:41:04 PM 60004 60154 1.00 4.00 0.00 5.00 9 pidstat
pidstat 命令有點像 top 命令對每個進程的統(tǒng)計摘要,但循環(huán)打印一個滾動的統(tǒng)計摘要來代替 top 的刷屏。其可用于實時查看,同時也可將你所看到的東西(復制粘貼)到你的調(diào)查記錄中。
上面的例子表明兩個 Java 進程正在消耗 CPU。%CPU 這列是所有 CPU 合計的;1591% 表示這個 Java 進程消耗了將近 16 個 CPU。
6. iostat -xz 1
$ iostat -xz 1
Linux 3.13.0-49-generic (titanclusters-xxxxx) 07/14/2015 _x86_64_ (32 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
73.96 0.00 3.73 0.03 0.06 22.21
Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
xvda 0.00 0.23 0.21 0.18 4.52 2.08 34.37 0.00 9.98 13.80 5.42 2.44 0.09
xvdb 0.01 0.00 1.02 8.94 127.97 598.53 145.79 0.00 0.43 1.78 0.28 0.25 0.25
xvdc 0.01 0.00 1.02 8.86 127.79 595.94 146.50 0.00 0.45 1.82 0.30 0.27 0.26
dm-0 0.00 0.00 0.69 2.32 10.47 31.69 28.01 0.01 3.23 0.71 3.98 0.13 0.04
dm-1 0.00 0.00 0.00 0.94 0.01 3.78 8.00 0.33 345.84 0.04 346.81 0.01 0.00
dm-2 0.00 0.00 0.09 0.07 1.35 0.36 22.50 0.00 2.55 0.23 5.62 1.78 0.03
[...]
這是用于查看塊設(shè)備(磁盤)情況的一個很棒的工具,無論是對工作負載還是性能表現(xiàn)來說。查看個列:
r/s, w/s, rkB/s, wkB/s:這些分別代表該設(shè)備每秒的讀次數(shù)、寫次數(shù)、讀取 kb 數(shù),和寫入 kb 數(shù)。這些用于描述工作負載。性能問題可能僅僅是由于施加了過大的負載。
await:以毫秒為單位的 I/O 平均消耗時間。這是應用程序消耗的實際時間,因為它包括了排隊時間和處理時間。比預期更大的平均時間可能意味著設(shè)備的飽和,或設(shè)備出了問題。
avgqu-sz:向設(shè)備發(fā)出的請求的平均數(shù)量。值大于 1 說明已經(jīng)飽和了(雖說設(shè)備可以并行處理請求,尤其是由多個磁盤組成的虛擬設(shè)備。)
%util:設(shè)備利用率。這個值是一個顯示出該設(shè)備在工作時每秒處于忙碌狀態(tài)的百分比。若值大于 60%,通常表明性能不佳(可以從 await 中看出),雖然它取決于設(shè)備本身。值接近 100% 通常意味著已飽和。
如果該存儲設(shè)備是一個面向很多后端磁盤的邏輯磁盤設(shè)備,則 100% 利用率可能只是意味著當前正在處理某些 I/O 占用,然而,后端磁盤可能遠未飽和,并且可能能夠處理更多的工作。
請記住,磁盤 I/O 性能較差不一定是程序的問題。許多技術(shù)通常是異步 I/O,使應用程序不會被阻塞并遭受延遲(例如,預讀,以及寫緩沖)。
7. free -m
$ free -m
total used free shared buffers cached
Mem: 245998 24545 221453 83 59 541
-/+ buffers/cache: 23944 222053
Swap: 0 0 0
右邊的兩列顯式:
buffers:用于塊設(shè)備 I/O 的緩沖區(qū)緩存。
cached:用于文件系統(tǒng)的頁面緩存。
我們只是想要檢查這些不接近零的大小,其可能會導致更高磁盤 I/O(使用 iostat 確認),和更糟糕的性能。上面的例子看起來還不錯,每一列均有很多 M 個大小。
比起第一行,-/+ buffers/cache 提供的內(nèi)存使用量會更加準確些。Linux 會把暫時用不上的內(nèi)存用作緩存,一旦應用需要的時候就立刻重新分配給它。所以部分被用作緩存的內(nèi)存其實也算是空閑的內(nèi)存。為了解釋這一點, 甚至有人專門建了個網(wǎng)站: linuxatemyram。
如果你在 Linux 上安裝了 ZFS,這一點會變得更加困惑,因為 ZFS 它自己的文件系統(tǒng)緩存不算入free -m。有時候發(fā)現(xiàn)系統(tǒng)已經(jīng)沒有多少空閑內(nèi)存可用了,其實內(nèi)存卻都待在 ZFS 的緩存里。
8. sar -n DEV 1
$ sar -n DEV 1
Linux 3.13.0-49-generic (titanclusters-xxxxx) 07/14/2015 _x86_64_ (32 CPU)
12:16:48 AM IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s %ifutil
12:16:49 AM eth0 18763.00 5032.00 20686.42 478.30 0.00 0.00 0.00 0.00
12:16:49 AM lo 14.00 14.00 1.36 1.36 0.00 0.00 0.00 0.00
12:16:49 AM docker0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
12:16:49 AM IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s %ifutil
12:16:50 AM eth0 19763.00 5101.00 21999.10 482.56 0.00 0.00 0.00 0.00
12:16:50 AM lo 20.00 20.00 3.25 3.25 0.00 0.00 0.00 0.00
12:16:50 AM docker0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
這個工具可以被用來檢查網(wǎng)絡接口的吞吐量:rxkB/s 和 txkB/s,以及是否達到限額。上面的例子中,eth0 接收的流量達到 22Mbytes/s,也即 176Mbits/sec(限額是 1Gbit/sec)
我們用的版本中還提供了 %ifutil 作為設(shè)備使用率(接收和發(fā)送的最大值)的指標。我們也可以用 Brendan 的 nicstat 工具計量這個值。一如 nicstat,sar 顯示的這個值是很難精確取得的,在這個例子里面,它就沒在正常的工作(0.00)。
9. sar -n TCP,ETCP 1
$ sar -n TCP,ETCP 1
Linux 3.13.0-49-generic (titanclusters-xxxxx) 07/14/2015 _x86_64_ (32 CPU)
12:17:19 AM active/s passive/s iseg/s oseg/s
12:17:20 AM 1.00 0.00 10233.00 18846.00
12:17:19 AM atmptf/s estres/s retrans/s isegerr/s orsts/s
12:17:20 AM 0.00 0.00 0.00 0.00 0.00
12:17:20 AM active/s passive/s iseg/s oseg/s
12:17:21 AM 1.00 0.00 8359.00 6039.00
12:17:20 AM atmptf/s estres/s retrans/s isegerr/s orsts/s
12:17:21 AM 0.00 0.00 0.00 0.00 0.00
這是一些關(guān)鍵的 TCP 指標的匯總視圖。這些包括:
active/s:每秒本地發(fā)起 TCP 連接數(shù)(例如,通過 connect())。
passive/s:每秒遠程發(fā)起的 TCP 連接數(shù)(例如,通過 accept())。
retrans/s:每秒重傳 TCP 次數(shù)。
active 和 passive 的連接數(shù)往往對于描述一個粗略衡量服務器負載是非常有用的:新接受的連接數(shù)(passive),下行連接數(shù)(active)??梢岳斫鉃?active 連接是對外的,而 passive 連接是對內(nèi)的,雖然嚴格來說并不完全正確(例如,一個 localhost 到 localhost 的連接)。
重傳是出現(xiàn)一個網(wǎng)絡和服務器問題的一個征兆。其可能是由于一個不可靠的網(wǎng)絡(例如,公網(wǎng))造成的,或許也有可能是由于服務器過載并丟包。上面的例子顯示了每秒只有一個新的 TCP 連接。
10. top
$ top
top - 00:15:40 up 21:56, 1 user, load average: 31.09, 29.87, 29.92
Tasks: 871 total, 1 running, 868 sleeping, 0 stopped, 2 zombie
%Cpu(s): 96.8 us, 0.4 sy, 0.0 ni, 2.7 id, 0.1 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem: 25190241+total, 24921688 used, 22698073+free, 60448 buffers
KiB Swap: 0 total, 0 used, 0 free. 554208 cached Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
20248 root 20 0 0.227t 0.012t 18748 S 3090 5.2 29812:58 java
4213 root 20 0 2722544 64640 44232 S 23.5 0.0 233:35.37 mesos-slave
66128 titancl+ 20 0 24344 2332 1172 R 1.0 0.0 0:00.07 top
5235 root 20 0 38.227g 547004 49996 S 0.7 0.2 2:02.74 java
4299 root 20 0 20.015g 2.682g 16836 S 0.3 1.1 33:14.42 java
1 root 20 0 33620 2920 1496 S 0.0 0.0 0:03.82 init
2 root 20 0 0 0 0 S 0.0 0.0 0:00.02 kthreadd
3 root 20 0 0 0 0 S 0.0 0.0 0:05.35 ksoftirqd/0
5 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kworker/0:0H
6 root 20 0 0 0 0 S 0.0 0.0 0:06.94 kworker/u256:0
8 root 20 0 0 0 0 S 0.0 0.0 2:38.05 rcu_sched
top 命令包含了很多我們之前已經(jīng)檢查過的指標??梢苑奖愕膱?zhí)行它來查看相比于之前的命令輸出的結(jié)果有很大不同,這表明負載是可變的。
top 的一個缺點是,很難看到數(shù)據(jù)隨時間變動的趨勢。vmstat 和 pidstat 提供的滾動輸出會更清楚一些。如果你不以足夠快的速度暫停輸出(Ctrl-S 暫停,Ctrl-Q 繼續(xù)),一些間歇性問題的線索也可能由于被清屏而丟失。
研究了一下
cpu溫度的數(shù)值由主板驅(qū)動供給windows,目前的現(xiàn)狀是許多PC兼容機不提供或沒安裝“專用的主板驅(qū)動”(比如大量的ghost集成裝機),連win都沒法獲知溫度,更別提win之上的Java。
在專用主板驅(qū)動安裝正常的win-java系統(tǒng)下可以:
import java.util.Scanner;
public class Test {
static public void main(String 土數(shù)[]) {
try {
final String cmd="wmic /namespace:\\\\root\\WMI path MSAcpi_ThermalZoneTemperature get CurrentTemperature";
Process p = Runtime.getRuntime().exec(cmd);
p.getOutputStream().close();//這句不寫就不執(zhí)行
Scanner sc=new Scanner(p.getInputStream());
sc.next();
float t=(sc.nextInt()-2732f)/10f;
sc.close();
System.out.println("當前CPU溫度:"+t);
p.waitFor();
} catch (Exception e) {
e.printStackTrace();
}
}
}
==
當前CPU溫度:41.0
linux下同樣依賴“主板驅(qū)動”, 數(shù)據(jù)提供給/dev/sensor
如果是遠程的linux系統(tǒng),可以使用java調(diào)用Telnet工具類執(zhí)行遠程腳本。代碼參考如下:package test;
import java.io.InputStream;
import java.io.PrintStream;
import org.apache.commons.net.telnet.TelnetClient;
public class Shell
{
private TelnetClient telnet = new TelnetClient();
private InputStream in;
private PrintStream out;
private char prompt = ';// 普通用戶結(jié)束
public Shell(String ip, int port, String user, String password)
{
try
{
telnet.connect(ip, port);
in = telnet.getInputStream();
out = new PrintStream(telnet.getOutputStream());
// 根據(jù)root用戶設(shè)置結(jié)束符
this.prompt = user.equals("root") ? '#' : '';
login(user, password);
}
catch (Exception e)
{
e.printStackTrace();
}
}
/**
* 登錄
*
* @param user
* @param password
*/
public void login(String user, String password)
{
// readUntil("login:");
readUntil("login:");
write(user);
readUntil("Password:");
write(password);
readUntil(prompt + "");
}
/**
* 讀取分析結(jié)果
*
* @param pattern
* @return
*/
public String readUntil(String pattern)
{
try
{
char lastChar = pattern.charAt(pattern.length() - 1);
StringBuffer sb = new StringBuffer();
char ch = (char)in.read();
while (true)
{
sb.append(ch);
if (ch == lastChar)
{
if (sb.toString().endsWith(pattern))
{
return sb.toString();
}
}
ch = (char)in.read();
System.out.print(ch);
}
}
catch (Exception e)
{
e.printStackTrace();
}
return null;
}
/**
* 寫操作
*
* @param value
*/
public void write(String value)
{
try
{
out.println(value);
out.flush();
}
catch (Exception e)
{
e.printStackTrace();
}
}
/**
* 向目標發(fā)送命令字符串
*
* @param command
* @return
*/
public String sendCommand(String command)
{
try
{
write(command);
return readUntil(prompt + "");
}
catch (Exception e)
{
e.printStackTrace();
}
return null;
}
/**
* 關(guān)閉連接
*/
public void disconnect()
{
try
{
telnet.disconnect();
}
catch (Exception e)
{
e.printStackTrace();
}
}
public static void main(String[] args) {
TelnetClient telnet = new TelnetClient();
try {
Shell she =new Shell("IP地址", 23, "用戶名", "密碼");
System.out.println(she);
System.out.println(she.sendCommand("ls"));
she.disconnect();
}catch (Exception e) {
// TODO: handle exception
}
}
}代碼是參考的網(wǎng)上源碼,使用時將System.out.println(she.sendCommand("ls"));中的ls命令換成查看CPU使用率的命令,例如top,vmstat,mpstat,prstat -J或者prstat -T 等命令。根據(jù)其結(jié)果做解析即可。
步驟:
1、在cmd中切換到編寫的代碼所保存的目錄下;
2、在cmd中輸入javac然后點空格,再點擊文件名和包括后綴名確定后,在存放編寫代碼的文件下會生成一個class的字節(jié)碼文件;
3、在cmd中輸入java然后點空格,輸入第二步中生成的字節(jié)碼的文件名,不需要后綴名,點擊確定即可運行代碼。
代碼就是程序員用開發(fā)工具所支持的語言寫出來的源文件,是一組由字符、符號或信號碼元以離散形式表示信息的明確的規(guī)則體系。計算機代碼稱為源代碼,是相對目標代碼和可執(zhí)行代碼而言的。 源代碼就是用匯編語言和高級語言寫出來的地代碼,目標代碼是指源代碼經(jīng)過編譯程序產(chǎn)生的能被cpu直接識別二進制代碼。