在OS X上是否存在Java特定的文件打开限制?

3

我在我的MacBook上使用Java打开文件时,发现最多只能打开10223个文件,而且我已经通过sysctl、launchd和ulimit设置了文件打开限制为65535,但是用C程序可以打开62282个文件。您知道Java是否遇到了额外的限制,以及如何更改它吗?

我用于测试的Java代码是:

import java.io.*;
import java.util.*;

class OpenFilesTest {
    private static List<InputStream> streams = new ArrayList<InputStream>();

    public static void main(String[] args) {
        for (int i = 0; true; i++) {
            FileInputStream f = null;
            try {
               f = new FileInputStream("/dev/null");
            } catch (Throwable e) {
               System.err.println(e.getMessage());
               e.printStackTrace();
               System.exit(1);
            }
            streams.add(f);
            System.out.println("We have " + (i + 1) + " InputStream's for /dev/null");
        }
    }
}

这将输出:
We have 1 InputStream's for /dev/null
We have 2 InputStream's for /dev/null
We have 3 InputStream's for /dev/null
...
We have 10221 InputStream's for /dev/null
We have 10222 InputStream's for /dev/null
We have 10223 InputStream's for /dev/null
/dev/null (Too many open files)
java.io.FileNotFoundException: /dev/null (Too many open files)
        at java.io.FileInputStream.open(Native Method)
        at java.io.FileInputStream.<init>(FileInputStream.java:138)
        at java.io.FileInputStream.<init>(FileInputStream.java:97)
        at OpenFilesTest.main(test.java:11)

我使用的C代码进行测试:

#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>

int main(void)
{
    for (int i = 0; 1; i++)
    {
        int fd = open("/dev/null", O_RDONLY);
        if (fd == -1)
        {
            perror("Couldn't open /dev/null one more time");
            exit(EXIT_FAILURE);
        } else {
            printf("Opened /dev/null %d times\n", i + 1);
        }
    }
}

以及它的输出:

Opened /dev/null 1 times
Opened /dev/null 2 times
Opened /dev/null 3 times
...
Opened /dev/null 62287 times
Opened /dev/null 62288 times
Opened /dev/null 62289 times
Couldn't open /dev/null one more time: Too many open files in system

关于该系统的更多相关信息:

$ uname -a
Darwin hostname.local 13.1.0 Darwin Kernel Version 13.1.0: Thu Jan 16 19:40:37 PST 2014; root:xnu-2422.90.20~2/RELEASE_X86_64 x86_64
$ java -version
java version "1.7.0_25"
Java(TM) SE Runtime Environment (build 1.7.0_25-b15)
Java HotSpot(TM) 64-Bit Server VM (build 23.25-b01, mixed mode)

我也在Linux(Debian Wheezy 7.4)上尝试过这个方法,在那里我可以使用这个Java程序打开大约65535个文件句柄。 这么多打开的文件句柄的基本用例是Scala中的服务器负载测试应用程序。

2
在我看来,for (int i = 0; true; i++) 真的很丑陋。如果你喜欢的话,为什么不只用 while(true) 或者 for(;;) 呢? - halex
@halex 因为 op 需要一个计数器。而且这只是一个可抛弃的测试程序,在这种情况下这些细节是完全无关紧要的。 - nos
1个回答

7
请查看特定于OS X JVM的选项,具体是针对MaxFDLimit: -XX:-MaxFDLimit 指示VM避免将文件描述符限制设置为默认最大值。默认行为是将限制设置为OPEN_MAX指定的值,即10240。通常,这是进程可以打开的文件数的最大值。然而,可以使用sysctl实用程序将此限制增加到用户指定的值。在这种情况下,您可能希望传递-XX:-MaxFDLimit以阻止Java VM限制打开文件的数量为10240。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接