Better cleanup your Process objects

Today we discovered that the java Process class does not close its three standard file handles when the Process terminates. Me, I didn’t find anything in the docs about this.

Running a loop where you create many Process objects may eventually reach your system’s limit of open file handles. Many systems will close the unused handles after a while, so the final effect might be time dependent. Have fun. We did ;-)

Here’s a test program that demonstrates the problem.

/** Demonstrate that java Process objects eat file handles
*  if their stdin, stderr and stdout channels are not explicitely
*  closed.
*
*  To see this, run the class until it says "done executing" and
*  do an lsof on the java process (should show 60 pipe channels).
*  Then uncomment the three close() calls and rerun the test.
*/
public class Exec {
public static void main(String[] args) throws Exception {
int NMAX=20;
final String command="bash -c exit";
System.err.println("Executing " + command + " " + NMAX + " times....");

for(int i=0; i<NMAX; i++) {
final Process p = Runtime.getRuntime().exec(command);
p.waitFor();

// These three calls are required to avoid eating file handles
// (at least under macosx and linux)
// p.getInputStream().close();
// p.getOutputStream().close();
// p.getErrorStream().close();

if(i % 10 == 0) System.err.print(".");
}

System.err.println("Done executing - press ENTER to exit");
System.in.read();
System.err.println("Done.");
}
}

One Response to Better cleanup your Process objects

  1. Praveen Prabhu says:

    Hi,

    This is great!!! It worked for me on AIX after I closed all three streams explicitely. It would fail otherwise exactly after 118 iterations each time I run the class.

    Let me put the error message that is thrown, so that search engines can store it and give this page to other people.

    “The process file table is full.”
    “Too many open files”

    Thanx Bertrand

    Praveen.

%d bloggers like this: