Gridgain パッケージ上で実行されている Java で書かれたかなり大規模で複雑なアプリケーションがあります。私が抱えている問題は、すべてのリクエストが開始される前に、このアプリケーションが約 1 日間リクエストを処理し続け、タイプ java.nio.channels.ClosedByInterruptException の例外が発生することです。
私の推測では、アプリケーションがファイル ハンドルを解放しておらず、1 日連続して使用した後、ファイル ハンドルがなくなり、リクエストの処理を続行できなくなります (各リクエストには、各グリッド ノードから複数のファイルを読み取る必要があります)。ファイル IO 操作のほとんどを、このようなクラスでラップしました。
package com.vlc.edge;
import com.vlc.common.VlcRuntimeException;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
public final class BufferedReaderImpl implements BufferedReader {
private java.io.BufferedReader reader;
public BufferedReaderImpl(final String source) {
this(new File(source));
}
public BufferedReaderImpl(final File source) {
try {
reader = new java.io.BufferedReader(new FileReader(source));
} catch (FileNotFoundException e) {
throw new VlcRuntimeException(e);
}
}
public BufferedReaderImpl(final Reader reader) {
this.reader = new java.io.BufferedReader(reader);
}
public String readLine() {
try {
return reader.readLine();
} catch (IOException e) {
throw new VlcRuntimeException(e);
}
}
public void close() {
try {
reader.close();
} catch (IOException e) {
throw new VlcRuntimeException(e);
}
}
}
問題は、この設計がファイル ハンドルを明示的に解放しないことだと思います。私の提案する解決策は、このようなファイナライズ メソッドを追加することです。
protected void finalize() throws Throwable
{
reader.close();
super.finalize();
}
これは明示的にこれを行います。(最終的に)問題は、これが何らかの影響を与える可能性があるかどうかです。java.io.BufferedReader などのクラスには、この種の問題に対処するメカニズムが既に備わっているのでしょうか?
編集:また、これが実際に問題であるかどうかを確認する方法も非常に高く評価されています...つまり、実行中のJVMにクエリを実行し、そのファイルハンドルの割り当てについて尋ねる方法はありますか?