对于 java 单元测试来说,确保正确关闭文件的良好模式是什么?



我的代码库中有一个问题,我们没有正确关闭文件句柄,或者可能是流。在非常繁重的负载下,我们最终会得到TooManyOpenFiles异常。根据lsof的输出,我们非常确定我们知道泄漏在哪里(在日志系统中),但我的问题是:我如何编写一个单元测试来检查,当它完成时,资源是否已正确关闭?是否有一种方法可以查询JRE以找出当前打开了多少文件?我是否可以拦截文件操作以监视它们?

我怀疑我将不得不仪表我的代码,以管理所有的文件I/O,计数引用,并确保他们被关闭的方式,但如果有人知道一个自上而下的解决方案类似于我上面提到的那些想法,这将是一个巨大的帮助!

既然您谈论的是测试,那么PowerMock http://code.google.com/p/powermock/可能会达到这个目的。如果我没有弄错的话,它使模拟静态方法和构造函数成为可能。因此,您可以模拟/监视构造函数和close方法,或者任何您需要释放资源的方法。

在我的测试中我尽量避免它,但在你描述的情况下,它可能值得麻烦。

您可以使用面向方面的编程(AOP)工具,如AspectJ来添加代码来计数打开/关闭的文件到FileInputStreamFileOutputStream。这很容易做到(当然,细节取决于工具),健壮且非侵入性。

看起来可以通过JMX观看。

有人在这里贴了代码:http://java-monitor.com/forum/showthread.php?t=130

您必须在JVM中启用JMX,如果您还没有启用的话。

您可以编写自己的"库";对于普通的IO类,FileInputStream等。它跟踪(在测试中)哪个调用者打开了它,如果它仍然打开,一个全局列表,等等。让它包上一个"real"。FileInputStream。然后在代码中到处使用它,而不是使用"normal"FileInputStream等

然后在你的单元测试结束时,你断言WrappedFileInputStreams.assertAllWereClosed或什么。

另一个选择是编写你的方法,使它们以某种方式接受FileinputStream作为参数,然后调用它们,然后断言你的参数出来"closed now"方法结束后。

或者如果你知道你将在linux上,做一个系统调用lsof,它不应该列出任何文件作为位置'(已删除)'。https://unix.stackexchange.com/a/64737/8337

由于某些原因,在OS X上这并不容易,它没有显示"(已删除)"但是你仍然可以通过循环lsof -p ...来检测文件是否消失,并检查每个文件是否实际上存在于文件系统中。

相关内容

  • 没有找到相关文章

最新更新