2017-07-11 724 views
2

我們的java應用程序在長時間運行後拋出「太多打開的文件」問題。 在調試問題時,看到有許多fds按照lsof輸出打開。找到哪個線程導致太多的打開文件問題,爲什麼lsof輸出中有重複的節點ID

# lsof -p pid | grep "pipe" | wc -l 
# lsof -p pid | grep "anon_inode" | wc -l 

--------------很少lsof的數據----- ------

COMMAND PID USER FD TYPE    DEVICE SIZE/OFF  NODE NAME 
java 23994 app 464u 0000    0,9  0  3042 anon_inode 
java 23994 app 465u 0000    0,9  0  3042 anon_inode 
java 23994 app 466r FIFO    0,8  0t0 962495977 pipe 
java 23994 app 467w FIFO    0,8  0t0 962495977 pipe 
java 23994 app 468r FIFO    0,8  0t0 963589016 pipe 
java 23994 app 469w FIFO    0,8  0t0 963589016 pipe 
java 23994 app 470u 0000    0,9  0  3042 anon_inode 
java 23994 app 471u 0000    0,9  0  3042 anon_inode 

如何找到許多類型爲FIFO和0000的開放式FD的根本原因。 在我們的應用程序中沒有太多的文件讀/寫操作。有很多TCP消息使用apache mina框架在內部使用Nio從流中讀取。

這是我的問題

  1. 我們已檢查過的/ proc/PID /任務/文件夾。有很多文件夾。它是否對應於線程ID?但根據jstack,有141個線程,因爲這個文件夾有209個子文件夾。
  2. 如何找到哪個線程導致fd泄漏?在我們的案例中,任務文件夾中的大部分文件夾對應於許多fds。即。/proc /進程/任務/線程ID/FD文件夾中有很多FD記錄
  3. 什麼是管的可能原因,並anon_inodes在lsof的
  4. 什麼是FD型0000
  5. 所有anon_inode的意義與同一個節點ID 3042 。 這是什麼意思?
+1

[Here](https://stackoverflow.com/questions/8170902/why-is-the-jdk-nio-using-so-many-anon-inode-file-descriptors)是一個相關的帖子/討論。這種泄漏的常見原因是沒有正確關閉和處理的插座和管道。這可能有助於隨時監測計數並將增長與外部因素聯繫起來。 –

+0

@AxelKemper:在任何給定的時間內都會打開近12000個套接字,並且大多數處於TIMED_WAIT狀態。那麼我可以將此問題與TIMED_WAIT套接字關聯嗎? – Albin

+0

隨時?系統重啓後,我預計線性增長。 –

回答

1

最有可能的是你打開資源,然後沒有正確關閉它們。確保你使用了適當的方法,比如try-with-resources或try-finally blocks來整理。

要找到問題,您應該將所有IO路由到一個類中,然後跟蹤打開和關閉,甚至可能記住堆棧跟蹤。然後,您可以查詢該資源,並查看資源泄漏的位置。

0

我們發現了這個問題。有一個代碼流創建了org.apache.mina.transport.socket.nio.NioSocketConnector,但在某些情況下沒有關閉。爲了找到這個問題,我們做了以下

  1. 我們啓用strace的在我們的Linux服務器
  2. 我們做了strace的爲兩分鐘的過程
  3. 我們可以找出線程ID導致問題
  4. 從jstack我們找到了線程類。
相關問題