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

如何找出Java应用程序当前打开的文件数?,java,Java,假设您的应用程序所做的很多工作都是处理文件内容的读取。不用说,打开然后关闭的文件,生活是美好的,除非。。。新文件的输入速度比旧文件的关闭速度快。这是我所处的困境 现在,有没有办法可靠地知道进程打开了多少文件?从JVM内部查看ls/proc/my_pid/fd | wc-l一样可靠的东西 我怀疑答案可能是操作系统特定的,所以让我补充一下,我正在Linux上运行Java。如果您想获得Java中ls/proc/my_pid/fd | wc-l的数量,您可以使用JMX 当您拥有MBeanServerCo

假设您的应用程序所做的很多工作都是处理文件内容的读取。不用说,打开然后关闭的文件,生活是美好的,除非。。。新文件的输入速度比旧文件的关闭速度快。这是我所处的困境

现在,有没有办法可靠地知道进程打开了多少文件?从JVM内部查看
ls/proc/my_pid/fd | wc-l
一样可靠的东西


我怀疑答案可能是操作系统特定的,所以让我补充一下,我正在Linux上运行Java。

如果您想获得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
这个数字表示您的进程(java应用程序)打开了多少fd。e、 你的商业文件被清点,那些罐子、图书馆的文件也被清点。如果您只想获得业务文件的计数,您必须自己实现一个计数器。或者,假设你想用shellscript来完成它,
grep
然后
wc-l

编辑

添加代码示例,但它只是一个示例。未在IDE中编写,未使用编译器进行测试。:)


在Unix上,一种方法是使用获取,如果是,则可以使用
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());
        }
    }
}

为了填写/添加答案:

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

详情见 这可能会引起一些混乱

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

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


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

很抱歉发布死灵公告,但是伙计们,你们忽略了lsof的-K选项,因为java有线程,每个线程都有自己的FD,它们都位于/proc/$PID/tasks/FD中/

这是一个巨大的区别:

root@xxx:/root# lsof -p 13553 | wc -l
612
root@xxx:/root# lsof -p 13553 -K | wc -l
112108

在ubuntu中,下面的
lsof
命令起作用

sudo lsof -c java

难道你不能在打开一个文件时增加一个计数,在关闭一个文件时减少一个计数吗?我想这是一种方法。。有更干净的解决方案吗?您可以用java执行该命令。看一看:我无法想象java会记住你打开了哪些文件以及打开了多少文件。我想最简单的方法就是。。。。检查在
/proc/self/fd/
中可以找到多少条目。这就是文件系统的用途:在运行时获取(和设置)进程信息。具有依赖于节点的读/写语义的值的层次树+将其映射到文件系统的流的层次树=unified win(好吧,以一种无类型的Plan 9方式-更好:打开一个JDBC连接到“某处”,然后使用SQL查询/更新sys&proc,有点像但更完整)单独执行此任务是否会增加FD的数量?似乎没有。谢谢这正是我要找的for@FDinoff回答得好!你知道如何在Windows中尝试这种行为吗?这个答案也有在macOS上工作的好处。不确定是否是我的操作系统,但如果使用
-K
参数,它将报告在所有进程中打开的文件。因此,如果我这样做:
lsof-p-K | wc-l
输出与
lsof | wc-l
相同。只有在不使用
-K
的情况下,它才能按预期工作。-K选项为所有流程任务提供了许多开放描述符。当您的流程生成一堆子流程时,这将非常有用,因为java应用程序会这样做
sudo lsof -c java