[英]Find out which class/instance holds a reference to an open file
I found a bug in logback that arises when it tries to delete a file that something else (such as an external process) holds a reference to.我在 logback中发现了一个错误,当它尝试删除其他内容(例如外部进程)引用的文件时,就会出现该错误。 Usually, the issue goes away if a I close the external process, but I have also experienced that, instead of a single file handle to the logfile that was to be deleted, suddenly I have two file handles for that Java process to the same file.
通常,如果我关闭外部进程,问题就会消失,但我也遇到过这样的情况,而不是要删除的日志文件的单个文件句柄,突然间我有该 Java 进程的两个文件句柄到同一个文件. To me, that seems like either two different classes are holding on to the same file, or there are two threads contending for the same resource.
对我来说,这似乎是两个不同的类持有同一个文件,或者有两个线程争用同一个资源。
In any case, I would like to know what is holding on to the file.无论如何,我想知道文件中保存了什么。 How can I get to know that?
我怎样才能知道呢? All I have to work with is the name of the file and the process id.
我需要处理的只是文件名和进程 ID。
Some casual browsing mentions taking a heap dump of the process and inspecting it using Visual VM and the OQL query language, but I am not totally sure how to do that on a Windows server, as the examples have all targetted Linux and its system of file descriptors.一些随意浏览提到获取进程的堆转储并使用 Visual VM 和 OQL 查询语言检查它,但我不完全确定如何在 Windows 服务器上执行此操作,因为示例都针对 Linux 及其文件系统描述符。
I normally use Eclipse MAT and OQL to get that type of information out of heap dump.我通常使用Eclipse MAT和 OQL 从堆转储中获取此类信息。
Yes, it is possible to use FileDescriptor information to find out your file object in heap.是的,可以使用 FileDescriptor 信息在堆中找出文件对象。
SELECT fd.parent.path.toString() FROM java.io.FileDescriptor fd
SELECT fd.parent.path.toString() FROM java.io.FileDescriptor fd
Assumption is that log file name is getting stored in somewhere and we are looking for that name.假设日志文件名存储在某个地方,我们正在寻找该名称。 This method takes little bit longer than the previous one as we are MAT has to search through all String objects.
此方法比前一个方法花费的时间稍长,因为 MAT 必须搜索所有 String 对象。
select * from java.lang.String s where s.toString().contains("myFileName")
select * from java.lang.String s where s.toString().contains("myFileName")
Once you get the GC root and if it is a thread then you can get stack trace also by:一旦你获得了 GC 根,如果它是一个线程,那么你也可以通过以下方式获得堆栈跟踪:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.