如何找出Java应用程序当前打开的文件数量?

假设您的应用程序执行的很多操作都涉及读取文件的内容。 不言而喻,打开然后关闭的文件和生活是好的,除非..新文件进入速度更快,然后旧文件关闭。 这是我发现自己陷入困境的腌制。

现在..有没有办法可靠地知道流程打开了多少文件? 像查看ls /proc/my_pid/fd | wc -l那样可靠的东西 ls /proc/my_pid/fd | wc -l来自JVM内部?

我怀疑答案可能是特定于操作系统的,所以让我补充一点,我在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()); } } } 

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

如果有MBeanServerConnection ,则可以获取属性“ OpenFileDescriptorCount ”。 这将给你与上面的ls..|wc -l相同的结果ls..|wc -l

还有另一个属性“ MaxFileDescriptorCount ”,它告诉你允许的最大数量。

如果你只是想知道这个值,而不是在你的代码中得到它,你可以做你的ls..|wc -l方式,或者从jconsole (用GUI)读取。

注意

 ls /proc/my_pid/fd | wc -l 

此数字表示您的进程(java应用程序)打开了多少个fd。 例如,您的业务文件计数,也是那些jar子,库文件也计算在内。 如果您只想获取业务文件的计数,则必须自己实施计数器。 或者,假设您想使用shellscript, 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()); } 

为了完成/添加答案:

许多人在基于Linux的系统中使用LSOF来监视文件描述符及其细节。 但是LSOF列出了UnixOperatingSystemMXBean.getOpenFileDescriptorCount()未返回的所有FD(CWD,MEM)。

详细信息可以在http://www.ibm.com/developerworks/aix/library/au-lsof.html中找到。这可能会引起一些混淆。

澄清UnixOperatingSystemMXBean.getOpenFileDescriptorCount()仅显示应用程序打开的文件描述符。 但是LSOF(lsof -a -p)列出了内核代表进程打开的其他文件描述符。

要仅列出应用程序级别FDS,可以过滤掉其他类型的FD

lsof -a -p yourprocid -d ^ txt,^ mem,^ cwd,^ rtd,^ DEL