所以我有一个在 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 文件句柄