java - 经过1天的压力测试,Java Gridgain应用程序开始失败

因此,我有一个运行在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运行时查询JVM或使用linux命令行工具来查找有关当前打开了哪些句柄的更多信息。 。

更新:我一直在使用命令行工具来询问lsof的输出,并且还没有看到任何证据表明文件句柄处于打开状态……网格中的每个节点都有一个非常稳定的打开文件配置文件,我可以看到上面的代码执行时发生了变化...但是它总是返回到稳定数量的打开文件中。

与此问题相关:Freeing java file handles

最佳答案

在几种情况下,文件句柄可能没有关闭:


可能还有其他一些代码可以打开文件。
可能还有其他一些代码调用createChannel(...)而没有调用fillContactBuffer(...)
如果channel.position(0)引发异常,则不会关闭该通道。解决方法是重新排列代码,以使以下语句位于try块内。

channel.position(0);
return new FileChannelImpl(channel);



编辑:查看堆栈跟踪,似乎这两个方法在不同的代码库中。我会责怪createChannel方法。即使它不是问题的根源,也可能会泄漏。它需要一个in内部finally子句来确保在发生异常时关闭通道。

这样的事情应该可以解决问题。请注意,您需要确保finally块在成功时不会关闭通道!

public static com.vlc.edge.FileChannel createChannel(final File file) {
    final FileChannel channel = null;
    try {
        channel = new FileInputStream(file).getChannel();
        channel.position(0);
        FileChannel res = new FileChannelImpl(channel);
        channel = null;
        return res;
    } 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 (...) {
                ... 
            }
        }
    }
}




跟进很多

考虑到消除了文件句柄泄漏的可能原因,我的下一个理论是服务器端实际上正在使用Thread.interrupt()中断其自己的线程。一些低级I / O调用通过引发异常来响应中断,而在此处引发的根异常看起来像是这样的异常之一。

这并不能解释为什么会发生这种情况,但是我可以说是一个服务器端框架,试图解决过载或死锁问题,这是一个疯狂的猜测。

本文翻译自 https://stackoverflow.com/questions/1605522/

网站遵循 CC BY-SA 4.0 协议,转载或引用请注明出处。

标签 java testing fileinputstream stress gridgain


相关文章:

java - 为什么Jersey不遵守动态绑定过滤器中的优先级?

java - 将多个对象写入包裹

java - 在没有ItemListener的情况下可以正常工作,但是当我添加它时,它给了我NullPointerException

android - 使用顺序测试用例的最佳实践是什么?

java - 为什么使用BufferedInputStream比使用FileInputStream更快地逐字节读取文件?

java - 片段提交中的非法语句异常

python - Django客户端不会在测试中删除

angular - Angular-Testing:如何使用TestBed为服务类提供配置对象?

java - 使用文件输入/输出流方法安全存储数据

java - FileInputStream错误Java