http://datoumao.blogspot.com/2012/09/linuxcputhread.html
ps H -eo user,pid,ppid,tid,time,%cpu,cmd --sort=%cpu
來源地址:
http://www.blogjava.net/hankchen/archive/2012/08/09/377735.html
原文內容:
一個應用占用CPU很高,除了確實是計算密集型應用之外,通常原因都是出現了死循環。
(友情提示:本博文章歡迎轉載,但請注明出處:hankchen,http://www.blogjava.net/hankchen)
以我們最近出現的一個實際故障為例,介紹怎么定位和解決這類問題。
根據top命令,發現PID為28555的Java進程占用CPU高達200%,出現故障。
通過ps aux | grep PID命令,可以進一步確定是tomcat進程出現了問題。但是,怎么定位到具體線程或者代碼呢?
首先顯示線程列表:
ps -mp pid -o THREAD,tid,time
找到了耗時最高的線程28802,占用CPU時間快兩個小時了!
其次將需要的線程ID轉換為16進制格式:
printf "%x\n" tid
最后打印線程的堆棧信息:
jstack pid |grep tid -A 30
找到出現問題的代碼了!
現在來分析下具體的代碼:ShortSocketIO.readBytes(ShortSocketIO.java:106)
ShortSocketIO是應用封裝的一個用短連接Socket通信的工具類。readBytes函數的代碼如下:
public byte[] readBytes(int length) throws IOException {
if ((this.socket == null) || (!this.socket.isConnected())) {
throw new IOException("++++ attempting to read from closed socket");
}
byte[] result = null;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
if (this.recIndex >= length) {
bos.write(this.recBuf, 0, length);
byte[] newBuf = new byte[this.recBufSize];
if (this.recIndex > length) {
System.arraycopy(this.recBuf, length, newBuf, 0, this.recIndex - length);
}
this.recBuf = newBuf;
this.recIndex -= length;
} else {
int totalread = length;
if (this.recIndex > 0) {
totalread -= this.recIndex;
bos.write(this.recBuf, 0, this.recIndex);
this.recBuf = new byte[this.recBufSize];
this.recIndex = 0;
}
int readCount = 0;
while (totalread > 0) {
if ((readCount = this.in.read(this.recBuf)) > 0) {
if (totalread > readCount) {
bos.write(this.recBuf, 0, readCount);
this.recBuf = new byte[this.recBufSize];
this.recIndex = 0;
} else {
bos.write(this.recBuf, 0, totalread);
byte[] newBuf = new byte[this.recBufSize];
System.arraycopy(this.recBuf, totalread, newBuf, 0, readCount - totalread);
this.recBuf = newBuf;
this.recIndex = (readCount - totalread);
}
totalread -= readCount;
}
}
}
問題就出在標紅的代碼部分。如果this.in.read()返回的數據小於等於0時,循環就一直進行下去了。而這種情況在網絡擁塞的時候是可能發生的。
至於具體怎么修改就看業務邏輯應該怎么對待這種特殊情況了。
最后,總結下排查CPU故障的方法和技巧有哪些:
1、top命令:Linux命令。可以查看實時的CPU使用情況。也可以查看最近一段時間的CPU使用情況。
2、PS命令:Linux命令。強大的進程狀態監控命令。可以查看進程以及進程中線程的當前CPU使用情況。屬於當前狀態的采樣數據。
3、jstack:Java提供的命令。可以查看某個進程的當前線程棧運行情況。根據這個命令的輸出可以定位某個進程的所有線程的當前運行狀態、運行代碼,以及是否死鎖等等。
4、pstack:Linux命令。可以查看某個進程的當前線程棧運行情況。
(友情提示:本博文章歡迎轉載,但請注明出處:hankchen,http://www.blogjava.net/hankchen)
http://binma85.iteye.com/blog/778986
開門見山,本文將簡述如何使用java thread dump來分析CPU高使用率以及線程死鎖問題。
一般java thread dump用於web開發中分析web容器或是應用服務器的性能問題還是比較常用並有效的。常用的入門級web容器Tomcat,以及高級別的jboss、websphere、weblogic等的性能調優問題都可以使用java thread dump來分析。
首先,闡述一下thread dump常用來解決的是何種問題
(1)高CPU使用
(2)線程死鎖
其次,使用步驟[以JBOSS為例]
1..get thread dump log
(1)找到應用程序所在的進程號,命令如下
- ps aux |grep 'jboss' | grep 'java'
、
獲取需要的PID
(2)執行sudo kill -3 PID獲取thread dump log(PID是第一步獲取)。
注意:在不同的linux環境下執行輸出的日志的地方可能不同。在IBM的PowerPC小型機上的linux上執行kill -3 pid會在工作目錄下產生類似javacore.20100409.161739.7614.0001.txt的文件。JBOSS默認環境下,thread dump log輸出到jboss console,所以thread dump信息會輸出到個人定義的控制台打印log中。
部分示例如下所以:
2010-10-08 20:27:42
Full thread dump Java HotSpot(TM) Server VM (16.3-b01 mixed mode):
"http-182.50.0.138-8084-6" daemon prio=10 tid=0x08ce5000 nid=0x6a4c in Object.wait() [0x87b5c000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x95eb81b0> (a org.apache.tomcat.util.net.JIoEndpoint$Worker)
at java.lang.Object.wait(Object.java:485)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.await(JIoEndpoint.java:415)
- locked <0x95eb81b0> (a org.apache.tomcat.util.net.JIoEndpoint$Worker)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:441)
at java.lang.Thread.run(Thread.java:619)
"http-182.50.0.138-8084-5" daemon prio=10 tid=0x08c2e000 nid=0x6a4b in Object.wait() [0x87bad000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x95ed0600> (a org.apache.tomcat.util.net.JIoEndpoint$Worker)
at java.lang.Object.wait(Object.java:485)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.await(JIoEndpoint.java:415)
- locked <0x95ed0600> (a org.apache.tomcat.util.net.JIoEndpoint$Worker)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:441)
at java.lang.Thread.run(Thread.java:619)
"ajp-127.0.0.1-8009-Acceptor-0" daemon prio=10 tid=0x894de800 nid=0x6a45 runnable [0x881f3000]
java.lang.Thread.State: RUNNABLE
at java.net.PlainSocketImpl.socketAccept(Native Method)
at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:390)
- locked <0x949c1288> (a java.net.SocksSocketImpl)
at java.net.ServerSocket.implAccept(ServerSocket.java:453)
at java.net.ServerSocket.accept(ServerSocket.java:421)
at org.apache.tomcat.util.net.DefaultServerSocketFactory.acceptSocket(DefaultServerSocketFactory.java:61)
at org.apache.tomcat.util.net.JIoEndpoint$Acceptor.run(JIoEndpoint.java:309)
at java.lang.Thread.run(Thread.java:619)
DefaultQuartzScheduler_QuartzSchedulerThread" prio=10 tid=0x8a460800 nid=0x6a38 sleeping[0x88818000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at org.quartz.core.QuartzSchedulerThread.run(QuartzSchedulerThread.java:394)
(3)獲取線程信息
使用上面的ps或者使用top命令也可以。獲取的線程信息如下所示:
27143 root 20 0 780m 376m 11m S 17 11.5 2:56.48 java
4839 root 20 0 778m 162m 11m S 10 5.0 1717:03 java
5049 root 20 0 764m 147m 11m S 4 4.5 1744:06 java
1 root 20 0 2100 720 624 S 0 0.0 0:28.08 init
2 root 15 -5 0 0 0 S 0 0.0 0:00.00 kthreadd
3 root RT -5 0 0 0 S 0 0.0 0:00.44 migration/0
第一列是十進制PID,需要轉化為16進制后才能和thread dump信息對應。
2.分析thread dump信息[不在列舉示例,只講思想]
(1)分析高CPU使用線程的thread dump信息,查找那些代碼導致高CPU使用。
(2)線程死鎖
a.為了發現線程動態變化,需要多次做thread dump,每次間隔10-30s為佳.
b.線程狀態用 runnable(正在運行)、waiting for monitor(主動等待)、waiting for monitor entry(死鎖)。所以我們最多的是關注runnable和entry類型的線程。
一種典型的死鎖是在server端多個應用同時使用同一個jboss資源,這時候需要將多個應用分不到不用的隊列中。
http://javag.iteye.com/blog/718243
參考文獻:
http://www.51testing.com/?uid-188107-action-viewspace-itemid-226468
1.分析內存的工具
Eclipse Memory Analyzer Tool(俗稱MAT),下載地址為: http://www.eclipse.org/mat/
使用Memory Analyzer tool(MAT)分析內存泄漏(一)
使用Memory Analyzer tool(MAT)分析內存泄漏(二) 使用前需要在linux上通過jmap -dump:format=b,file={$filename} ${pid}方式將heap的內存快照文件給dump出來,然后就可以通過上面的MAT進行分析了。注意dump出來的文件名要以bin作為后綴名不然可能識別不了哦.
例如: jmap -dump:format=b,file=a.bin 2298
2.線程狀態分析
"exec-613" Id=713 in BLOCKED on lock=com.ss.nio.ClientFactory@2262ce5f owned by tomcatThreadPool-exec-553 Id=623
"exec-553" Id=623 in TIMED_WAITING on lock=com.ss.nio.AbstractRequest@35ce75e at java.lang.Object.wait(Native Method)
"NioProcessor-1" Id=700 in RUNNABLE (running in native) at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method) at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:215) at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:65) at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:69) at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:80)
"RMI TCP Connection(8)-172.25.3.81" Id=698 in RUNNABLE at sun.management.ThreadImpl.getThreadInfo0(Native Method) at sun.management.ThreadImpl.getThreadInfo(ThreadImpl.java:145) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597)
RUNNABLE(正在運行的,消耗cpu) TIMED_WAITING(等待被分配到cpu運行的,現在不消耗cpu) BLOCKED(被阻塞,在阻塞解除前不能被分配cpu執行,現在不消耗cpu)
exec-613占用了鎖,exec-553需要的鎖被exec-613占用無法執行處於blocked狀態.
NioProcessor-1正在運行,並且他的方法在調用native方法.
RMI TCP Connection(8)-172.25.3.81正在運行.
(一) jinfo jinfo打印一個給定的Java進程或核心文件或一個遠程調試服務器的Java配置信息。配置信息包括Java系統屬性和JVM命令行標志(更多信息,請參考《jinfo-Configuration Info》)。 (二) jmap jmap:如果這個工具不使用任何選項(除了pid或core選項)運行,那么它顯示類似於Solaris的pmap工具所輸出的信息。這個工具支持針對Java堆可觀察性的若干其它選項。 在Java SE 6平台中,新加入了一個-dump選項。這樣可以使jmap能夠把Java堆信息復制到一個文件中,然后我們可以使用新的jhat命令(見下面一節)來分析它。 jmap -dump選項並不使用Solaris libproc來實現實時處理;而是,它運行當前正運行的JVM中的一小段代碼,由此來實現堆復制。既然這種堆復制代碼運行於JVM內部,那么其速度是比較快的。堆復制的效果大致相當於實現一次"完全的GC"(對整個堆的垃圾收集),再加上把該堆的內容寫入到文件中。實現堆復制的另外一種可能的思路是使用 gcore來進行核心復制並且運行"jmap -dump"(這與以"離線"方式運行的核心復制形成對照)。
可以輸出某個java進程內存內對象的情況,甚至可以將VM 中的heap,以二進制輸出成文本。
[root@B1943 ~]# jmap -histo 710 >mem.txt(可使用文本對比工具對比出GC回收了哪些對象) 該文件中內容如: num #instances #bytes class name ---------------------------------------------- 4: 1202692 67350752 java.io.ObjectStreamClass$WeakClassKey |
[root@B1943 ~]#jmap -dump:format=b,file=mem.bin 710 (將該進程heap輸出到mem.bin文件中,使用二進制形式。該文件可供其他 分析工具使用,如eclipse memory analyser) 注:jmap使用的時候jvm是處在假死狀態的,只能在服務癱瘓的時候為了解決問題來使用,否則會造成服務中斷 |
(三) jstack jstack等價於Solaris的pstack工具。jstack打印所有的Java線程的堆棧跟蹤信息(可選地包括本機幀信息),請參考《jstack-堆棧跟蹤》。關於鎖和死鎖的信息也可以被打印,請參考java.util.concurrent locks。 top 時 H顯示線程情況 PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 29390 mqq 15 0 1696m 1.3g 8784 S 100 16.3 1:46.19 java 29889 mqq 16 0 1696m 1.3g 8784 S 6 16.3 1:23.26 java 29904 mqq 15 0 1696m 1.3g 8784 S 2 16.3 0:14.87 java 29849 mqq 15 0 1696m 1.3g 8784 S 1 16.3 0:14.68 java 29388 mqq 16 0 1696m 1.3g 8784 S 1 16.3 0:12.55 java 29850 mqq 15 0 1696m 1.3g 8784 S 1 16.3 0:15.26 java 其中線程29390轉換為16進制為0x72ce,可以查出對應比較耗時線程在做什么 jstack 29364|grep -A10 72ce "Thread-2" prio=10 tid=0x00002aab0b603c00 nid=0x72ce runnable [0x000000004133b000..0x000000004133baa0] java.lang.Thread.State: RUNNABLE at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method) at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:215) at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:65) at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:69) - locked <0x00002aaab2d972e8> (a sun.nio.ch.Util$1) - locked <0x00002aaab2d972d0> (a java.util.Collections$UnmodifiableSet) - locked <0x00002aaab2283470> (a sun.nio.ch.EPollSelectorImpl) at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:80) at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:84)
(四) jsadebugd jsadebugd依附到一個Java進程或核心文件並且擔當一個調試服務器的作用。遠程客戶,例如jstack、jmap和jinfo,都能夠通過Java RMI依附到該服務器。 (五) jhat jhat是一個Java堆復制瀏覽器。這個工具分析Java堆復制文件(例如,由上面的 "jmap -dump"所產生的)。Jhat啟動一個允許堆中的對象在web瀏覽器中進行分析的web服務器。這個工具並不是想用於應用系統中而是用於"離線"分析。"jhat工具是平HIDDEN立的",其意思是,它可以被用來觀察在任何平台上所產生的堆復制。例如,我們有可能在Linux系統上使用jhat來觀察一個在Solaris OS上所產生的堆復制。
(六)jstat 查出gc情況
很強大的監視jvm內存工具,可用來查看堆內各個部分的使用量,以及加載類的數量。使用時,需指定java進程號。 一般使用 -gcutil 查看gc情況。
[root@B1943 ~]# jstat -class 710(顯示加載class的數量,及所占空間等信息) Loaded Bytes Unloaded Bytes Time 11242 24450.0 41 65.8 30.25 |
jstat -compiler pid:顯示VM實時編譯的數量等信息。
jstat -gc pid:可以顯示gc的信息,查看gc的次數及時間。其中最后五項,分別是young gc的次數,young gc的時間 ,full gc的次數,full gc的時間,gc的總時間。 jstat -gccapacity pid:可以顯示VM內存中三代(young,old,perm)對象的使用和占用大小,如:PGCMN顯示的是 最小perm的內存使用量,PGCMX顯示的是perm的內存最大使用量,PGC是當前新生成的perm內存占用量,PC是當 前perm內存占用量。
語法結構如下:jstat [Options] vmid [interval] [count] Options — 選項,我們一般使用 -gcutil 查看gc情況 vmid — VM的進程號,即當前運行的java進程號 interval– 間隔時間,單位為秒或者毫秒 count — 打印次數,如果缺省則打印無數次 S0 — Heap上的 Survivor space 0 區已使用空間的百分比 S1 — Heap上的 Survivor space 1 區已使用空間的百分比 E — Heap上的 Eden space 區已使用空間的百分比 O — Heap上的 Old space 區已使用空間的百分比 P — Perm space 區已使用空間的百分比 YGC — 從應用程序啟動到采樣時發生 Young GC 的次數 YGCT– 從應用程序啟動到采樣時 Young GC 所用的時間(單位秒) FGC — 從應用程序啟動到采樣時發生 Full GC 的次數 FGCT– 從應用程序啟動到采樣時 Full GC 所用的時間(單位秒) GCT — 從應用程序啟動到采樣時用於垃圾回收的總時間(單位秒)
實例使用1:
[root@localhost bin]# jstat -gcutil 25444
S0 S1 E O P YGC YGCT FGC FGCT GCT
11.63 0.00 56.46 66.92 98.49 162 0.248 6 0.331 0.579
實例使用2:
[root@localhost bin]# jstat -gcutil 25444 1000 5
S0 S1 E O P YGC YGCT FGC FGCT GCT
73.54 0.00 99.04 67.52 98.49 166 0.252 6 0.331 0.583
73.54 0.00 99.04 67.52 98.49 166 0.252 6 0.331 0.583
73.54 0.00 99.04 67.52 98.49 166 0.252 6 0.331 0.583
73.54 0.00 99.04 67.52 98.49 166 0.252 6 0.331 0.583
73.54 0.00 99.04 67.52 98.49 166 0.252 6 0.331 0.583
jps
與ps命令類似,用來顯示本地的java 進程,查看本地運行着幾個java應用,並顯示進程號。
[root@B1943 ~]# jps(只顯示進程號) 23813 Jps 710 Bootstrap 792 Bootstrap |
[root@B1943 ~]# jps -v(顯示jvm參數) 23852 Jps -Denv.class.path=.:/usr/jdk1.6.0_21/lib/dt.jar:/usr/jdk1.6.0_21/lib/tools.jar -Dapplication.home=/usr/jdk1.6.0_21 -Xms8m 710 Bootstrap -Xms2048m -Xmx2048m -XX:NewRatio=2 -XX:PermSize=256M -XX:MaxPermSize=512M -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.util.logging.config.file=/root/zhusj/apache-tomcat-6.0.18_1/conf/logging.properties -Dcom.sun.management.jmxremote.port=8799 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.endorsed.dirs=/root/zhusj/apache-tomcat-6.0.18_1/endorsed -Dcatalina.base=/root/zhusj/apache-tomcat-6.0.18_1 -Dcatalina.home=/root/zhusj/apache-tomcat-6.0.18_1 -Djava.io.tmpdir=/root/zhusj/apache-tomcat-6.0.18_1/temp |
sar : 既能收集系統 CPU 、硬盤網絡設備等動態數據,更能查看二進制數據文件等。
用法:
sar [參數選項] t [n] [-o file] ( t 為采樣間隔秒,必須有, n 為采樣次數,可選,默認值 1 )
參數說明:
-A 顯示所有歷史數據,通過讀取/var/log/sar 目錄下的所有文件,並把它們分門別類的顯示出來; -b 通過設備的I/O 中斷讀取設置的吞吐率; -B 報告內存或虛擬內存交換統計; -c 報告每秒創建的進程數; -d 報告物理塊設備(存儲設備)的寫入、讀取之類的信息,如果直觀一點,可以和p 參數共同使用,-dp -f 從一個二進制的數據文件中讀取內容,比如sar -f filename ; -n 分析網絡設備狀態的統計,后面可以接的參數有DEV 、EDEV 、NFS 、NFSD 、SOCK 等。比如-n DEV -o 把統計信息以二進制格式寫入一個文件,比如-o filename ; -u 報告CPU 利用率的參數; -P 報告每個處理器應用統計,用於多處理器機器,並且啟用SMP 內核才有效; -p 顯示友好設備名字,以方便查看,也可以和-d 和-n 參數結合使用;
-r 內存和交換區占用統計; -t 這個選項對從文件讀取數據有用,如果沒有這個參數,會以本地時間為標准讀出; -v 報告inode, 文件或其它 內核表的資源占用信息; -w 報告系統交換活動的信息; 每少交換數據的個數; -W 報告系統交換活動吞吐信息; -x 用於監視進程的,在其后要指定進程的PID 值; -X 用於監視進程的,但指定的應該是一個子進程ID ;
CPU利用率:
[root@B1943 ~]#sar -u 1 5 Linux 2.6.18-53.el5 (B1943) 2011年01月13日 14時58分08秒 CPU %user %nice %system %iowait %steal %idle 14時58分09秒 all 0.00 0.00 0.00 0.00 0.00 100.00 14時58分10秒 all 0.50 0.00 0.00 0.00 0.00 99.50 14時58分11秒 all 0.00 0.00 0.00 0.00 0.00 100.00 14時58分12秒 all 0.00 0.00 0.00 0.00 0.00 100.00 14時58分13秒 all 0.00 0.00 0.00 0.00 0.00 100.00 Average: all 0.10 0.00 0.00 0.00 0.00 99.90 |
%usr cpu 用戶模式下時間(百分比) %sys cpu 系統模式下時間(百分比)
%nice 表示 CPU 在用戶層優先級的百分比, 0 表示正常; %iowait cpu 等待輸入 / 輸出完成(時間百分比) %idle cpu 空閑時間(百分比)
將動態信息寫入文件中:
[root@localhost ~]#sar -u 1 5 > sar000.txt [root@localhost ~]# cat sar000.txt
也可以輸出到一個二進制的文件中,然后通過 sar 來查看;
[root@localhost ~]#sar -u 1 5 -o sar002 [root@localhost ~]# sar -f sar002
網絡設備的吞吐情況:
[root@B1943 ~]#sar -n DEV 2 5 |grep eth0 15時04分12秒 eth0 6.97 1.00 0.54 0.07 0.00 0.00 0.00 15時04分14秒 eth0 7.50 1.50 0.71 0.16 0.00 0.00 0.00 15時04分16秒 eth0 6.00 1.50 0.43 0.16 0.00 0.00 0.00 15時04分18秒 eth0 7.50 1.50 0.58 0.16 0.00 0.00 0.00 15時04分20秒 eth0 7.50 1.50 0.50 0.16 0.00 0.00 0.00 Average: eth0 7.09 1.40 0.55 0.14 0.00 0.00 0.00 |
IFACE:設備名; rxpck/s:每秒收到的包; rxbyt/s:每秒收到的所有包的體積 txbyt/s:每秒傳輸的所有包的體積; rxcmp/s:每秒收到數據切割壓縮的包總數; txcmp/s:每秒傳輸的數據切割壓縮的包的總數; rxmcst/s:每秒收到的多點傳送的包。
iostat:用法:
iostat [ -c | -d ] [ -k ] [ -t ] [ -V ] [ -x [ device ] ] [ interval [ count ] ]> outputfile
其中, -c為匯報CPU的使用情況; -d為匯報磁盤的使用情況; -k表示每秒按kilobytes字節顯示數據; -x可獲得更多信息; interval指每次統計間隔的時間; count指按照這個時間間隔統計的次數。
[root@B1943 ~]# iostat -d -k -x Linux 2.6.18-53.el5 (B1943) 2011年01月13日 Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await svctm %util sda 0.02 4.10 0.11 1.77 2.11 23.45 27.24 0.00 1.15 0.63 0.12 rrqm/s:每秒這個設備相關的讀取請求有多少被Merge了(當系統調用需要讀取數據的時候,VFS將請求發到各個FS,如果FS發現不同的讀取請求讀取的是相同Block的數據,FS會將這個請求合並Merge);
wrqm/s:每秒這個設備相關的寫入請求有多少被Merge了。
rsec/s:每秒讀取的扇區數;
wsec/s:每秒寫入的扇區數。
r/s:The number of read requests that were issued to the device per second;
w/s:The number of write requests that were issued to the device per second;
await:每一個IO請求的處理的平均時間(單位是微秒)。這里可以理解為IO的響應時間,一般地系統IO響應時間應該低於5ms,如果大於10ms就比較大了。
%util:在統計時間內所有處理IO時間,除以總共統計時間。例如,如果統計間隔1秒,該設備有0.8秒在處理IO,而0.2秒閑置,那么該設備的%util = 0.8/1 = 80%,所以該參數暗示了設備的繁忙程度。一般地,如果該參數是100% 表示設備已經接近滿負荷運行了(當然如果是多磁盤,即使%util是100%,因為磁盤的並發能力,所以磁盤使用未必就到了瓶頸)。
[root@B1943 ~]# iostat -d -k Linux 2.6.18-53.el5 (B1943) 2011年01月13日
Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn sda 1.88 2.11 23.45 1122861 12458568
tps:該設備每秒的傳輸次數(Indicate the number of transfers per second that were issued to the device.)。“
一次傳輸”意思是“一次I/O請求”。多個邏輯請求可能會被合並為“一次I/O請求”。“一次傳輸”請求的大小是未知的。 kB_read/s:每秒從設備(drive expressed)讀取的數據量;
kB_read:讀取的總數據量;
kB_wrtn/s:每秒向設備(drive expressed)寫入的數據量;
kB_wrtn:寫入的總數量數據量;這些單位都為Kilobytes。
iostat -cdx 1 >outfile
cat outfile
vmstat: 也可以輸出到文件vmstat > outputfile
Procs r: The number of processes waiting for run time. b: The number of processes in uninterruptable sleep. w: The number of processes swapped out but otherwise runnable.
Memory swpd: the amount of virtual memory used (kB). free: the amount of idle memory (kB). buff: the amount of memory used as buffers (kB).
Swap si: Amount of memory swapped in from disk (kB/s). so: Amount of memory swapped to disk (kB/s).
IO bi: Blocks sent to a block device (blocks/s). bo: Blocks received from a block device (blocks/s).
System in: The number of interrupts per second, including the clock. cs: The number of context switches per second.
CPU These are percentages of total CPU time. us: user time sy: system time id: idle time
文件句柄數Too many open files
問題描述:java .io.IOException: Too many open files
[root@B1943 ~]#ulimit -a(查看文件句柄數) core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited max nice (-e) 0 file size (blocks, -f) unlimited pending signals (-i) 71680 max locked memory (kbytes, -l) 32 max memory size (kbytes, -m) unlimited open files (-n) 1024 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 819200 max rt priority (-r) 0 stack size (kbytes, -s) 10240 cpu time (seconds, -t) unlimited max user processes (-u) 71680 virtual memory (kbytes, -v) unlimited file locks (-x) unlimited [root@B1943 ~]# ulimit -n 1024 |
ulimit應該是用戶的限制 ,如果太小則修改大小:ulimit -n 2048
如果要重啟后仍生效,則可修改/etc/security/limits.conf,后面加上: * - nofile 2048 (此時type用“-”,表示hard和soft同時設定。domain設置為星號代表全局,也可以針對不同的用戶做出不同的限制 )
/proc/sys/fs/file-max應該是系統級的限制
[root@B1943 ~]# cat /proc/sys/fs/file-max(查看) 8192 [root@B1943 ~]# echo 65536 > /proc/sys/fs/file-max(修改) |
如果要重啟后仍生效,則可修改 /etc/sysctl.conf,加上:fs.file-max = 65536
另外還有一個,/proc/sys/fs/file-nr
只讀,可以看到整個系統目前使用的文件句柄數量