java 单元测试有什么好的模式可以确保正确关闭文件?

发布于 2024-12-06 08:18:44 字数 288 浏览 0 评论 0原文

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

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

I have an issue in my codebase where we are not properly closing file handles, or probably streams. We eventually get a TooManyOpenFiles exception under very heavy load. Based on the output of lsof, we are pretty sure we know where the leak is (in our logging system), but my question is: how can I write a unit test that checks, when it's complete, that resources have been closed properly? Is there a way to query the JRE to find out how many files are currently open? Can I somehow intercept file operations so I can monitor them?

I suspect I will have to instrument my code in order to manage all the file I/O, count references, and make sure they are getting closed that way, but if anyone knows of a top-down solution akin to those ideas I mentioned above, that would be a huge help!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

£噩梦荏苒 2024-12-13 08:18:44

Since you are talking about Tests, PowerMock http://code.google.com/p/powermock/ might do the trick. It makes it possible to mock static methods and constructors if I am not mistaken. So you could mock/spy on the constructors and on the close methods or what ever you need for freeing the resources.

I try to avoid it in my tests but in the case which you describe it might be worth the hassle.

李不 2024-12-13 08:18:44

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

You can use aspect-oriented programming (AOP) tool like AspectJ to add code to count open/closed files to FileInputStream and FileOutputStream. This is fairly easy to do (details depend on the tool, of course) robust and noninvasive.

橙味迷妹 2024-12-13 08:18:44

看来您可以通过 JMX 观看此内容。

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

如果您尚未启用 JMX,则必须在 JVM 中启用 JMX。

Looks like you can watch this via JMX.

Someone posted code here:
http://java-monitor.com/forum/showthread.php?t=130

You'll have to enable JMX in your JVM if you haven't already.

心碎无痕… 2024-12-13 08:18:44

您可以为普通 IO 类、FileInputStream 等编写自己的“库”。它跟踪(在测试中)调用者打开它的内容(如果它仍然打开)、全局列表等。让它包装一个“真正的”FileInputStream。
然后在代码中的任何地方使用它而不是“普通”FileInputStream 等。

然后在单元测试结束时断言 WrappedFileInputStreams.assertAllWereClosed 或其他什么。

另一种选择是编写您的方法,以便它们以某种方式接受 FileinputStream 作为参数,然后调用它们,然后断言您的参数在方法结束后“立即关闭”。

或者,如果您知道您将使用 Linux,请对 lsof 进行系统调用,它不应将任何文件列为位置“(已删除)”。 https://unix.stackexchange.com/a/64737/8337

由于某些原因,在 OS X 上并非如此很简单,它不会显示“(已删除)”,但您仍然可以通过循环 lsof -p ... 并检查每个文件是否确实存在于文件系统上来检测文件是否已消失...

You could write your own "library" for the normal IO classes, FileInputStream, etc. That tracks (in test) what caller opened it, if it's still open, a global list, etc. Have it wrap a "real" FileInputStream.
Then use that everywhere in your code instead of a "normal" FileInputStream et al.

Then at the end of your unit test you assert WrappedFileInputStreams.assertAllWereClosed or what have you.

Another option would be to write your methods so they accept FileinputStream as a parameter somehow, then call them, then assert your parameter comes out "closed now" after the method ends.

Or if you know you'll be on linux, do a system call to lsof and it should not list any files as location '(deleted)'. https://unix.stackexchange.com/a/64737/8337

For some reason on OS X it's not that easy, it doesn't show "(deleted)" but you could still detect if the file is gone by looping over lsof -p ... and checking if each file is actually there on the file system...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文