Java 性能優化實戰記錄(2)---句柄泄漏和監控


 

前言: Java不存在內存泄漏, 但存在過期引用以及資源泄漏. (個人看法, 請大牛指正) 

這邊對文件句柄泄漏的場景進行下模擬, 並對此做下簡單的分析.
如下代碼為模擬一個服務進程, 忽略了句柄關閉, 造成不能繼續正常服務的小場景.

 1 public class FileHandleLeakExample {
 2 
 3     public static String readContentFromFile(String filename) {
 4         StringBuilder sb = new StringBuilder();
 5         BufferedReader br = null;
 6         try {
 7             br = new BufferedReader(new FileReader(filename));
 8             String line = null;
 9             while ( (line = br.readLine()) != null ) {
10                 sb.append(line).append("\n");
11             }
12         } catch (Exception e) {
13             System.err.println(e.getMessage());
14             exit(1);
15         } finally {
16 //          模擬疏忽關掉句柄的操作
17 //            try {
18 //                br.close();
19 //            } catch (IOException e) {
20 //                e.printStackTrace();
21 //            }
22         }
23         return sb.toString();
24     }
25 
26     public static void main(String[] args) {
27         while ( true ) {
28             FileHandleLeakExample.readContentFromFile("1.txt");
29         }
30     }
31 
32 }
33 
34 /*
35     輸入結果如下:
36     1.txt (Too many open files)
37 */

 

句柄泄漏導致, 進程服務達到系統設置的上限, 進而導致不可服務狀態. 這就需要必要的監控了.

如何監控或者如何在測試階段能提前發現呢?

在linux中, 一切皆句柄, 比如file, socket都是, 每個進程都有自己的上限, 一旦超過這個上限,系統就會限制並拒絕相應的資源請求.
這個設定如下所示:
ulimit -a             # ulimit -n 列出open file的個數

由此可見系統對於一般進程的文件句柄上限為 1024. 

但對上面那個java進程進行觀察, 卻發現如下不一致的地方,如下所示:

jps   #列出java進程的pid列表

cd /proc/<pid>/fd  #通過linux的虛擬文件系統,進入該java進程的系統信息 

ls | wc -l                #統計其總開打開的文件句柄數

其擁有的句柄個數4095與系統限制的句柄數上限1024相差太遠, 這是什么情況?

實際上系統的限制, 分為兩種,一種為soft limit, 另一種為hard limit, soft limit相當於一個warning, 而hard limit系統則不允許超越.

執行如下命令:

ulimit -a -H         # ulimit -n -H 列出open file的句柄數

現在系統的open file 4096的上限與java進程擁有的句柄數4095保持了一致.

關於soft limit和hard limit的區別, 請參閱如下鏈接:

http://blog.163.com/zhangjie_0303/blog/static/9908270620112233523316/

 

對於文件句柄數, 還可以借用lsof命令來查閱

lsof -p <pid>

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM