【问题标题】:Java file limit on OSX lower than in bashOSX 上的 Java 文件限制低于 bash
【发布时间】:2013-05-03 07:30:57
【问题描述】:

我提高了我的 macbook pro 的最大文件数限制,以便 Elasticsearch 可以处理更多文件,但它不起作用。

我运行命令“ulimit -a”,它说“打开的文件”是 100,000。我可以像这样运行一个简单的 shell 脚本:

export counter=0
while (true) ; do touch "/tmp/foo${counter}" ; export counter=`expr $counter + 1` ; done

而且我能够创建大量文件(在我终止脚本之前超过 60,000 个)。

但是,使用 Java 代码在“/tmp”目录的空子目录中创建 RandomAccessFiles,我只能创建 10,232 个文件,然后我得到错误:java.io.FileNotFoundException(打开的文件太多)。这是我的 Java 代码:

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

public class max_open_files {
    public static void main(String ... args) throws Exception {
        File testDir = new File("/tmp/tempsubdir");
        testDir.mkdirs();

        List<File> files = new LinkedList<File>();
        List<RandomAccessFile> fileHandles = new LinkedList<RandomAccessFile>();

        try {
            while (true) {
                File f = new File(testDir, "tmp" + fileHandles.size());
                RandomAccessFile raf = new RandomAccessFile(f, "rw");
                files.add(f);
                fileHandles.add(raf);
            }
        } catch (Exception ex) {
            System.out.println(ex.getClass() + " " + ex.getMessage());
        }

        for (RandomAccessFile raf : fileHandles) raf.close()

        for (File f : files) f.delete();

        System.out.println("max open files: " + fileHandles.size());
    }
}

此 java 代码类似于 Elasticsearch 中测试文件数量限制的代码(在 maxOpenFiles 方法中的 FileSystemUtils 类中)。所以 Elasticsearch 和我的 Java 程序有同样的问题。

为什么 shell 脚本可以生成比 Java 代码(我的和 Elasticsearch 的)更多的文件?为什么Java代码无法识别系统对文件数量的高限制?

更新 5 月 13 日下午 4:50 CDT:我创建了一个 C 版本的测试程序,以查看限制是否是特定于 Java 的,并且看起来确实如此。下面的C版本可以打开32765个文件,而Java代码限制为10232个文件。

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

int main(int argc, const char *argv) {
    char name[100];
    FILE *fp;
    int ndx;

    for (ndx = 0; ndx < 50000; ndx++) {
        sprintf(name, "/tmp/foo%d.txt", ndx);
        fp = fopen(name, "w");
        if (fp == NULL) {
            fprintf(stdout, "Can not create file %d\n", ndx);
            return 1;
        }
        fprintf(fp, "hello %d", ndx);
    }

    return 0;
}

【问题讨论】:

    标签: java macos bash elasticsearch


    【解决方案1】:

    在 bash 脚本中,您不打开文件,您只需创建它们,然后删除对它们的引用。在 Java 版本中,您似乎保留了对它的引用,因此打开了文件的数量。顺便说一句,我现在意识到这并不能真正回答为什么 Java 只能有 10.000 个(VM 的 + 文件),而不是 100.000 个......

    【讨论】:

    • 当回答的人说自己“我现在意识到这并不能真正回答为什么 Java 只能有 10.000 ( +VM 的文件)”。很高兴找到一个真正的答案。
    【解决方案2】:

    Java Virtual Machine Option Reference for Mac

    -XX:- MaxFDLimit

    指示 VM 避免将文件描述符限制设置为默认最大值。默认行为是将限制设置为 OPEN_MAX 指定的值,即 10240。通常,这是进程可以打开的最大文件数。但是,可以使用 sysctl 实用程序将此限制增加到用户指定的值。在这种情况下,您可能需要通过 -XX:-MaxFDLimit 来阻止 Java VM 将打开文件数限制为 10240。

    【讨论】:

    • 这对我来说似乎不适用于 OpenJDK 11。有人知道这个标志是否已更改吗?文档有点难找。
    猜你喜欢
    • 2012-08-12
    • 2018-11-30
    • 1970-01-01
    • 2016-11-23
    • 1970-01-01
    • 2014-08-18
    • 1970-01-01
    • 2013-06-13
    • 2014-05-02
    相关资源
    最近更新 更多