5

私のプログラムでは、一連のファイルをスキャンしてその内容を読み取るループがあります。この問題は、約 1500 ファイルの繰り返しで発生し、再現できないようです (または (私が) 理解できません)。

問題:

java.io.FileNotFoundException: /path/to/file//myFile (Too many open files)

例外はこのメソッドを指しています:

private static String readFileAsRawString(File f) throws IOException {

    FileInputStream stream = new FileInputStream(f); // <------------Stacktrace
    try{
      FileChannel fc = stream.getChannel();
      MappedByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());

      return Charset.defaultCharset().decode(bb).toString();
    } finally {
        stream.close();
    }
}

この方法を QA で 20,000 個以上のファイルに対して実行しましたが、問題はないようです。

この問題の原因となる、上に貼り付けたコードに何か問題がありますか?

4

3 に答える 3

3

マッピングが疑わしい。AMappedByteBufferはその より長く存続できFileChannel、ガベージ コレクションされるまで有効です。GC を実行するのに十分なガベージがないかもしれませんが、おそらく特定のプラットフォームでは、参照されていないバッファによってファイル ハンドルが保持されます。


明示的なガベージ コレクションが無効になっていない限り ( )、例外をキャッチして を呼び出し、再試行することで-XX:-DisableExplicitGC、これをテストできるはずです。System.gc()2回目の試行でうまくいく場合、それはあなたの問題です. System.gc()ただし、恒久的な修正として呼び出すことはお勧めできません。全体的に最高のパフォーマンスを発揮するソリューションには、ターゲット プラットフォームでのプロファイリングが必要です。

于 2012-11-03T00:20:02.353 に答える
2

この単純なタスクには MappedByteBuffer を使用しないでください。それらが解放される明確に定義された時間はありません。ファイルを開いて、読んで、閉じるだけです。

于 2012-11-03T00:46:43.297 に答える
-1

高速化するにはあまりにも多くのファイルを開いていると思います。これをテストするために wait() を追加してみてください。次に、開いているファイルを追跡する静的カウンターを追加し、多くのファイルが既に開いている場合は、待機メカニズムを追加します...

于 2012-11-03T00:21:38.387 に答える