4

Elasticsearch がより多くのファイルを処理できるように、Macbook Pro の最大ファイル数の制限を増やしましたが、機能しません。

コマンド「ulimit -a」を実行すると、「開いているファイル」は 100,000 と表示されます。次のような単純なシェル スクリプトを実行できます。

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 (Too many open files)。ここに私の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 コードは、(maxOpenFiles メソッドの FileSystemUtils クラスで) ファイル数の制限をテストする Elasticsearch のコードに似ています。したがって、Elasticsearch には、私の Java プログラムと同じ問題があります。

シェル スクリプトが Java コード (私のコードと Elasticsearch のコード) よりも多くのファイルを作成できるのはなぜですか? ファイル数のシステム上限が Java コードで認識されないのはなぜですか?

Update May 13 4:50pm CDT: C バージョンのテスト プログラムを作成して、制限が Java 固有のものであるかどうかを確認しました。以下の C バージョンは 32,765 個のファイルを開くことができますが、Java コードは 10,232 個のファイルに制限されています。

#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;
}
4

2 に答える 2

13

Mac 用 Ja​​va 仮想マシン オプション リファレンス

-XX:- MaxFDLimit

ファイル記述子の制限をデフォルトの最大値に設定しないよう VM に指示します。デフォルトの動作では、制限を OPEN_MAX で指定された値 (10240) に設定します。通常、これはプロセスが開くことができるファイルの最大数です。ただし、sysctl ユーティリティを使用して、この制限をユーザー指定の値まで増やすことができます。このような状況では、-XX:-MaxFDLimit を渡して、Java VM が開いているファイルの数を 10240 に制限しないようにすることができます。

于 2013-05-14T05:31:56.747 に答える
4

bash スクリプトでは、ファイルを開くのではなく、ファイルを作成するだけで、後でそれらへの参照を削除します。Javaバージョンでは、それへの参照を保持しているように見えるため、開いているファイルの数です。ところで、Java が 100.000 ではなく 10.000 (+ VM のファイル) しか持てない理由について、これは実際には答えていないことに気付きました...

于 2013-05-08T22:35:36.543 に答える