假設你的應用程序做了很多處理閱讀文件內容的工作。不言而喻,那些打開的文件然後關閉,生活是好的,除非..新文件進入更快,然後舊文件關閉。這是一個情況,我發現自己在困境之中。如何找出Java應用程序當前打開的文件數量?
現在..是有辦法可靠地知道有多少文件是由進程打開?像JVM內部看ls /proc/my_pid/fd | wc -l
一樣可靠嗎?
我懷疑答案可能是操作系統特定的,所以讓我補充一點,我在Linux上運行的Java。
假設你的應用程序做了很多處理閱讀文件內容的工作。不言而喻,那些打開的文件然後關閉,生活是好的,除非..新文件進入更快,然後舊文件關閉。這是一個情況,我發現自己在困境之中。如何找出Java應用程序當前打開的文件數量?
現在..是有辦法可靠地知道有多少文件是由進程打開?像JVM內部看ls /proc/my_pid/fd | wc -l
一樣可靠嗎?
我懷疑答案可能是操作系統特定的,所以讓我補充一點,我在Linux上運行的Java。
在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());
}
}
}
如果你想在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());
}
示例代碼爲完成/添加答案的緣故:
很多人使用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
無法每當你打開一個文件時你只需增加一個計數......並且每當你關閉一個文件時就遞減一次? – NominSim 2013-05-03 14:13:40
我想這是做這件事的一種方式..是否有更清潔的解決方案? – JAM 2013-05-03 14:29:27
您可以在java中執行該命令。看看: http://docs.oracle.com/javase/6/docs/api/java/lang/Runtime.html 我無法想象,Java記憶你打開了哪些和多少文件。 – mmirwaldt 2013-05-03 14:32:05