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