In Java how do you get a count of the open file handles?

  • strict warning: Non-static method view::load() should not be called statically in /hermes/walnaweb12a/b57/moo.greydragoncom/nodsw/sites/all/modules/views/views.module on line 906.
  • strict warning: Declaration of views_handler_argument::init() should be compatible with views_handler::init(&$view, $options) in /hermes/walnaweb12a/b57/moo.greydragoncom/nodsw/sites/all/modules/views/handlers/views_handler_argument.inc on line 744.
  • strict warning: Declaration of views_handler_filter::options_validate() should be compatible with views_handler::options_validate($form, &$form_state) in /hermes/walnaweb12a/b57/moo.greydragoncom/nodsw/sites/all/modules/views/handlers/views_handler_filter.inc on line 607.
  • strict warning: Declaration of views_handler_filter::options_submit() should be compatible with views_handler::options_submit($form, &$form_state) in /hermes/walnaweb12a/b57/moo.greydragoncom/nodsw/sites/all/modules/views/handlers/views_handler_filter.inc on line 607.
  • strict warning: Declaration of views_handler_filter_boolean_operator::value_validate() should be compatible with views_handler_filter::value_validate($form, &$form_state) in /hermes/walnaweb12a/b57/moo.greydragoncom/nodsw/sites/all/modules/views/handlers/views_handler_filter_boolean_operator.inc on line 159.
Leeland's picture

I just did a code review on a change to a production service in Java which was having problems with left over open handles. Lets face it the change is so simple as to be ridiculous. We just added an explicit file.close() call.

However, part of the process of code review is to examine the unit tests which where added to insure the problem is indeed fixed. But, from Java how do you get a count of the open file handles? Although that by itself is a bit of a sticky problem, it is far more interesting to ask how do you write a unit test to confirm that the open handles are not increasing pre and post a particular function call? Essentially Java will happily toss an exception that there are too many open files. Looking at the Java docs on that particular IO Exception:


Exception in thread "main" java.io.IOException: Cannot open file "/tmp/tooManyFiles.65537": error=24, Too many open files

On Linux its not difficult to find out if a program is leaking file handles by either counting the open handles in the /proc directory or even easier running the command 'lsof -p ##;' (replace ## with the PID). So you can kick of any program on Linux and then while it is running run the command 'ls /proc/##/fd | wc -w' or more accurately 'lsof -p ##'. My problem is that this will not work on Windows, or many other OSs on which Java runs.

So how to do this from Java? Well I thought about it and reasoned that it should be possible to the the handle count before calling a method, call the method and when it returns count the open handles. Do this a few hundred times and you should see little or no change in the file handle count. Which would be easy if there was a hook to get at the open file handles held by the Virtual Machine.

Well there is an open bug with Sun on this:

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4404721

I wish I could say I found a really nifty Java only solution to this. But, truth is I needed to get a solution done and move on. Since the code was for a Linux target we could take the short cut and call out to Runtime.getRuntime().exec() to run the 'lsof -p ##' command and parse the results. BTW watch out for the 3 extra file handles opened by the above call! We tripped over that next.

Which leads me to the very pertinent side note that I also discovered another interesting and related issue with Java in that you need to explicitly close the output file handles (stdin, stdout and stderr) allocated by any exec process. The Java RunTime.exec() (e.g. 'Process p = Runtime.getRuntime().exec("/bin/true");') does not release them after the invoked program terminates.

Which is interesting and known but not mentioned in the javadoc for the process class and just about all the authoritative resources get this wrong. For example:

http://www.ibm.com/developerworks/java/library/j-tiger09304.html
http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html

There is even an acknowledged bug report that was filed on this in 2006 asking for the documentation to be improved:

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6462165

Thread Slivers eBook at Amazon