File descriptor leaks under java 1.6
Kurt Miller
lists at intricatesoftware.com
Mon Mar 31 14:01:17 PDT 2008
On Sunday 23 March 2008 3:13:33 pm Dominic Bishop wrote:
> I have an application that makes use of 2 way socket communcations, so uses
> Socket/ServerSocket, this is all standard IO, no java.nio is involved.
>
> When running this under diablo 1.5 everything works fine, watching allocated
> file descriptors with lsof shows nothing abnormal whatsoever.
>
> If I run this under a port build JDK 1.6 then it starts leaking file
> descriptors originating from TCP, until eventually the available descriptors
> are exhausted and the application crashes with a 'too many open files'
> error.
>
> I've tried both patchset 3 and 4 of the port, under amd64 and i386
> architecture FreeBSD 6.3 and the same problem occurs under all
> circumstances.
>
> The problem file descriptors in the lsof output appear as:
>
> java 47065 djb 46u IPv4 0xffffff01354a4000 0t0 TCP *:*
> (CLOSED)
> java 47065 djb 47u IPv4 0xffffff006b2875f0 0t0 TCP *:*
> (CLOSED)
> java 47065 djb 48u IPv4 0xffffff0001bdcbe0 0t0 TCP *:*
> (CLOSED)
> java 47065 djb 49u IPv4 0xffffff015924c000 0t0 TCP *:*
> (CLOSED)
> java 47065 djb 50u IPv4 0xffffff01375078e8 0t0 TCP *:*
> (CLOSED)
>
> I ran the application with -Xrunhprof enabled under jdk 1.6 and then used
> jhat to look at the resulting dump.
>
> I managed to determine from this that the FD number (ie 46u) corresponds to
> the 'fd' field in a java.io.FileDescriptor instance.
>
> Using the Object Query Language in jhat I went looking for these file
> descriptor instances using:
>
> 'select f from java.io.FileDescriptor f where f.fd == ##'
>
> For numbers which were genuine file descriptors (ie connected sockets etc)
> this would always find the file descriptor instance and walking through the
> referenced objects/fields it was clear it had located the correct file
> descriptor. By that I mean the connected address, or for actual files, the
> pointed to filename agreed with the lsof output.
>
> If however I tried this query looking for file descriptor numbers which lsof
> was showing in the CLOSED state then it would fail to find them at all, so
> no FileDescriptor instance in the java heap referenced these file descriptor
> numbers.
>
> To make sure I did a:
> 'select f.fd from java.io.FileDescriptor f'
>
> This listed the 'fd' field value for all instances of java.io.FileDescriptor
> in the heap, I had numbers for the ones expected (ie actual bound sockets,
> open files/pipes etc that lsof showed) as well as quite a few set to -1 and
> a lot set to 0. Presumably these last 2 are either newly created instances
> or ones awaiting garbage collection.
>
> I've basically completely run out of ideas as to where these file
> descriptors are leaking, and given the working behaviour under diablo 1.5
> and the lack of references in the heap dump I'm no longer sure that this is
> actually a problem in my code.
>
> Anyone more familiar with the JVM internals got any suggestions as to where
> to go next?
Hi Dominic,
My next step would be to create a minimal test case and post it here to see if
others can reproduce it. A minimal test case is also useful to narrow the scope
of what JVM code needs to be reviewed to find the cause.
-Kurt
More information about the freebsd-java
mailing list