3

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. 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. 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.

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.

oligofren
  • 20,744
  • 16
  • 93
  • 180

1 Answers1

7

I normally use Eclipse MAT and OQL to get that type of information out of heap dump.

route#1: using java.io.FileDescriptor

Yes, it is possible to use FileDescriptor information to find out your file object in heap.

  1. Run this OQL command:

SELECT fd.parent.path.toString() FROM java.io.FileDescriptor fd

  1. Once you get that object list, you have to check paths and find out the file you are interested in.
  2. Then right-click on that object > Merge Shortest Path To GC Roots > Exclude all phantom/weak/soft etc. references
  3. You may need to drill-down a bit to find out the GC Root which is holding onto that file

route#2: searching all Strings

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.

  1. Run this OQL command:

select * from java.lang.String s where s.toString().contains("myFileName")

  1. Once you get that object list, you have to check paths and find out the file you are interested in.
  2. Repeat step#3 and #4 as mentioned above to get the GC root.

Once you get the GC root and if it is a thread then you can get stack trace also by:

  1. Right-click on that thread object
  2. Java Basics > Thread Details
suv3ndu
  • 221
  • 5
  • 12