5

こんにちは私はブロックを使用するいくつかのコードを持っています

RandomAccessFile file = new RandomAccessFile("some file", "rw");
FileChannel channel = file.getChannel();

// some code
String line = "some data";
ByteBuffer buf = ByteBuffer.wrap(line.getBytes());
channel.write(buf);

channel.close();
file.close();

ただし、このアプリケーションの特徴は、平均で4000を超える多数の一時ファイルを生成する必要があることです(パーティションテーブルへのHiveの挿入に使用されます)。

問題は時々私が例外をキャッチすることです

Failed with exception Too many open files

アプリの実行中。

ファイルがすでに閉じられていて、もう使用されていないことをOSに伝える方法があるとしたら、私は傷つきます。

channel.close();
file.close();

開いているファイルの数は減りません。Javaコードでこれを行う方法はありますか?

で開いているファイルの最大数をすでに増やしました

#/etc/sysctl.conf:
kern.maxfiles=204800
kern.maxfilesperproc=200000
kern.ipc.somaxconn=8096

更新: 問題を解決しようとしたので、コードを分けて各部分を調査しました(ファイルの作成、ハイブへのアップロード、ファイルの削除)。

クラス「File」または「RandomAccessFile」の使用は、「開いているファイルが多すぎます」という例外を除いて失敗します。

最後に私はコードを使用しました:

FileOutputStream s = null;
FileChannel c = null;

try {
    s = new FileOutputStream(filePath);
    c = s.getChannel();
    // do writes
    c.write("some data"); 
    c.force(true);
    s.getFD().sync();

} catch (IOException e) {
    // handle exception
} finally {
    if (c != null)
        c.close();
    if (s != null)
        s.close();
}

そして、これは大量のファイルで機能します(それぞれ5KBのサイズで20Kでテストされています)。コード自体は、前の2つのクラスのように例外をスローしません。ただし、本番コード(ハイブ付き)にはまだ例外がありました。そして、JDBCを介したハイブ接続がその理由のようです。さらに調査します。

4

3 に答える 3

4

OSが使用できる開いているファイルハンドルの数は、プロセスが開くことができるファイルハンドルの数と同じではありません。ほとんどのUNIXシステムでは、プロセスごとのファイルハンドルの数が制限されています。ほとんどの場合、JVMの1024ファイルハンドルのようなものです。

a)JVMを起動するシェルのulimitをより高い値に設定する必要があります。('ulimit -n 4000'のようなもの)

b)ファイルの「ファイナライズ」を妨げるリソースリークがないことを確認する必要があります。

于 2011-05-24T16:36:00.617 に答える
3

必ずfinally{}ブロックを使用してください。何らかの理由で例外が発生した場合、記述されたコードでクローズが発生することはありません。

于 2011-05-24T18:39:34.023 に答える
0

これは正確なコードですか?ループですべてのファイルを開き、最後にすべてのファイルを閉じるコードを記述して、この問題を引き起こしている可能性がある1つのシナリオを考えることができるからです。完全なコードを投稿してください。

于 2011-05-24T15:42:08.523 に答える