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

时间:2013-05-03 14:01:06

标签: java

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

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

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

5 个答案:

答案 0 :(得分:29)

在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());
        }
    }
}

答案 1 :(得分:9)

如果您想获得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。例如您的业​​务文件计数,也是那些罐子,库文件也计算在内。如果您只想获取业务文件的计数,则必须自己实施计数器。或者,假设您想使用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());
}

答案 2 :(得分:7)

为了完成/添加答案:

许多人在基于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

答案 3 :(得分:2)

很抱歉,您可能忽略了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

答案 4 :(得分:0)

在ubuntu中,下面的add_one <- function(data, var, na_if_val = NULL) { data %>% mutate(across({{ var }}, as.numeric)) %>% {if( is.null(na_if_val) ) . # <--- the dot means: "return the preexisting dataframe" else na_if(x = ., y = na_if_val) } %>% mutate(across({{ var }}, add, 1)) } 命令有效

lsof