2013-05-03 22 views
22

假設你的應用程序做了很多處理閱讀文件內容的工作。不言而喻,那些打開的文件然後關閉,生活是好的,除非..新文件進入更快,然後舊文件關閉。這是一個情況,我發現自己在困境之中。如何找出Java應用程序當前打開的文件數量?

現在..是有辦法可靠地知道有多少文件是由進程打開?像JVM內部看ls /proc/my_pid/fd | wc -l一樣可靠嗎?

我懷疑答案可能是操作系統特定的,所以讓我補充一點,我在Linux上運行的Java。

+4

無法每當你打開一個文件時你只需增加一個計數......並且每當你關閉一個文件時就遞減一次? – NominSim 2013-05-03 14:13:40

+0

我想這是做這件事的一種方式..是否有更清潔的解決方案? – JAM 2013-05-03 14:29:27

+0

您可以在java中執行該命令。看看: http://docs.oracle.com/javase/6/docs/api/java/lang/Runtime.html 我無法想象,Java記憶你打開了哪些和多少文件。 – mmirwaldt 2013-05-03 14:32:05

回答

23

在unix系統中的一種方式是使用ManagementFactory得到OperatingSystemMxBean,如果它是一個UnixOperatingSystemMXBean可以使用getOpenFileDescriptorCount()方法。

下面

import java.lang.management.ManagementFactory; 
import java.lang.management.OperatingSystemMXBean; 
import com.sun.management.UnixOperatingSystemMXBean; 
public class OpenFileCount{ 
    public static void main(String[] args){ 
     OperatingSystemMXBean os = ManagementFactory.getOperatingSystemMXBean(); 
     if(os instanceof UnixOperatingSystemMXBean){ 
      System.out.println("Number of open fd: " + ((UnixOperatingSystemMXBean) os).getOpenFileDescriptorCount()); 
     } 
    } 
} 
+0

執行此任務本身是否會增加FD的數量? – JAM 2013-05-03 14:50:01

+0

似乎不是。謝謝。這正是我期待的 – JAM 2013-05-03 16:32:07

6

如果你想在java中獲得ls /proc/my_pid/fd | wc -l的數量,你可以使用JMX

當你有MBeanServerConnection,你可以得到屬性 「OpenFileDescriptorCount」。這會給你與上面的ls..|wc -l相同的結果。

也有另一種屬性「MaxFileDescriptorCount」,它告訴你的允許最大數。

如果您只想知道該值,但沒有在代碼中獲取該值,則可以使用ls..|wc -l方式,或者從jconsole(使用GUI)進行讀取。

注意

ls /proc/my_pid/fd | wc -l 

這個數字表明有多少FD通過你的進程(Java應用程序)打開。例如你的商業文件被計算在內,那些罐子,庫文件也被計算在內。如果您只想獲得業務文件的數量,則必須自行實施計數器。或者說你想用shell腳本做到這一點,grep出來的東西然後wc -l

編輯

添加的代碼示例,但它僅僅是一個例子。沒有用IDE編寫,沒有用編譯器測試過。 :)

ObjectName oName = new ObjectName("java.lang:type=OperatingSystem"); 
MBeanServerConnection conn ; // you should get the connection following the api, take a look the java api/ google some example 
javax.management.AttributeList list = conn.getAttributes(oName, new String[]{"OpenFileDescriptorCount", "MaxFileDescriptorCount"}); 
for(Attribute attr: list.asList()){ 
    System.out.println(attr.getName() + ": " + attr.getValue()); 
} 
5

示例代碼爲完成/添加答案的緣故:

很多人使用LSOF在基於Linux的系統,以監測文件描述符和他們的詳細資料。然而LSOF列出了所有類型的未通過UnixOperatingSystemMXBean.getOpenFileDescriptorCount()返回的FD(CWD,MEM)的。

詳細信息可在http://www.ibm.com/developerworks/aix/library/au-lsof.html 這可能會導致一些混淆。

爲了澄清UnixOperatingSystemMXBean.getOpenFileDescriptorCount()只顯示應用程序打開的文件描述符。 但LSOF(lsof -a -p)列出了由內核代表進程打開的其他文件描述符。

要只列出應用水平FDS一個可以過濾掉其他類型的文件描述符

lsof的-a -p yourprocid -d^TXT,^ MEM,^ CWD的,^ RTD,^ DEL

相關問題