强制java释放java中的所有文件锁/句柄



我的Java应用程序(相当多的代码)做了很多文件操作。在我的应用程序中,我需要将文件从一个位置移动到另一个位置,为此,我使用了JDK7中的Files.move方法。

当我尝试这样做时,我会收到一个错误,告诉我该文件正在使用中。我知道,锁定这个资源的是我代码的某个部分。

在调用移动/重命名文件的函数之前,我如何强制Java应用程序释放所有锁?

如果这不可能,有没有一种简单的方法来检查我的代码的哪一部分锁定了文件?考虑到代码的数量,在我的整个代码库中查找未关闭的文件句柄将是一场噩梦

感谢

在调试器的帮助下,您可以查看内存中对象的所有实例(在Netbeans中,这将是Windows|Debugging|Loaded Classes,然后右键单击->显示实例)。然后,您可以查看您拥有的所有FileInputStream/FileOutputStream实例,并确定那些指向要移动的文件的实例。一旦你找到了文件的引用,你就可以看到谁仍然持有该引用。

如果没有人持有对该文件的引用,则可能在没有调用close()的情况下丢弃了该实例,并且通常只有在垃圾回收之后才会释放该文件。这使得前面的方法毫无用处,因为我认为调试器会自动为您垃圾收集这些流。也许您可以在流构造函数中放置一个条件断点,并告诉它只有在构造函数参数引用您的文件时才停止。

如果你找不到任何东西,作为最后的手段,你可以试着在移动操作之前打几个System.gc()电话,看看你是否有任何改进。显然,这只是一个快速而肮脏的解决方案,给你一些时间,直到你发现真正的问题。

File()Object不会锁定文件,但FileStream(FileInputStream/FileOutputStream)会锁定它。因此,您必须为您的Streams编写一个HelperClass(例如Singleton),记录所有的Streams。

但请注意,如果您的代码中存在漏洞,修复该漏洞比关闭所有文件要好得多

除了正确关闭流(最好在try.. finally块内)之外的任何解决方案都将是一项糟糕的工作,并有可能使事情变得比现在更不稳定。

我知道在大型代码库中修复这个问题很痛苦。如果你不想在代码中跋涉,FindBugs擅长定位未关闭的流。有一个Eclipse插件,您可以将它发现的错误过滤为您感兴趣的错误。

最新更新