そのため、gridgain の上で実行されているアプリケーションがあり、約 12 ~ 24 時間のストレス テストで問題なく動作し始めました。この期間が過ぎると、アプリケーションは突然、例外 java.nio.channels.ClosedByInterruptException ですべてのクエリに応答し始めます (完全なスタック トレースはhttp://pastie.org/664717にあります)。
失敗している方法は(@stephencフィードバックを使用するように編集されています)
public static com.vlc.edge.FileChannel createChannel(final File file) {
FileChannel channel = null;
try {
channel = new FileInputStream(file).getChannel();
channel.position(0);
final com.vlc.edge.FileChannel fileChannel = new FileChannelImpl(channel);
channel = null;
return fileChannel;
} catch (FileNotFoundException e) {
throw new VlcRuntimeException("Failed to open file: " + file, e);
} catch (IOException e) {
throw new VlcRuntimeException(e);
} finally {
if (channel != null) {
try {
channel.close();
} catch (IOException e){
// noop
LOGGER.error("There was a problem closing the file: " + file);
}
}
}
}
呼び出し元の関数がオブジェクトを正しく閉じる
private void fillContactBuffer(final File signFile) {
contactBuffer = ByteBuffer.allocate((int) signFile.length());
final FileChannel channel = FileUtils.createChannel(signFile);
try {
channel.read(contactBuffer);
} finally {
channel.close();
}
contactBuffer.rewind();
}
アプリケーションは基本的に分散ファイル パーサーとして機能するため、これらのタイプの操作を多数実行します (通常、ノードごとのクエリごとに約 10 のチャネルを開きます)。一定期間が経過すると、ファイルを開くことができなくなったようです。なぜこれが起こっているのかを説明するのに途方に暮れています.それを下げて修正します。ファイルハンドルの枯渇に関連している可能性がある場合は、確実に見つけるためのヒントを聞きたいです...つまり、実行中にJVMを照会するか、Linuxコマンドラインツールを使用して、現在開いているハンドルに関する詳細情報を見つけます.
更新:コマンド ライン ツールを使用して lsof の出力を調査しましたが、ファイル ハンドルが開いたままになっているという証拠は確認できませんでした... グリッド内の各ノードには、開いたファイルの非常に安定したプロファイルがあります。上記のコードが実行されると変化が見られます...しかし、常に安定した数の開いているファイルに戻ります。
この質問に関連: Java ファイル ハンドルの解放