JDK-6462165 : (process) Preach Process file handle hygiene
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.lang
  • Affected Version: 6
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • OS: generic
  • CPU: generic
  • Submitted: 2006-08-21
  • Updated: 2017-08-10
Related Reports
Relates :  
Relates :  
Relates :  
Relates :  
Description
A Process object causes 3 operating system file handles to be allocated.
Users of e.g. FileOutputStream are being educated to use constructions like

OutputStream os = new FileOutputStream(...);
try {...} // use os
finally { os.close(); }

It is less obvious that Process also allocates 3 file handles that should be
explicitly closed to avoid hitting operating system limits.

Something like

    static void closeStreams(Process p) throws IOException {
	p.getInputStream().close();
	p.getOutputStream().close();
	p.getErrorStream().close();
    }

Process p = ...
try {...} // use p
finally { closeStreams(p); }

Perhaps closeStreams should be added to the Process class to enable this idiom?

There is also the issue of making sure that the subprocess terminates when it
is no longer useful.  If the subprocess exists for no other purpose than to
communicate with its Java parent, then it should be terminated like this:

Process p = ...
try {...} // use p
finally { closeStreams(p); p.destroy(); }

(unless, of course, the subprocess will notice that its stdio streams have
been closed and automatically die)

See also 
4801027: (process spec) Clarify need to invoke Process.destroy

Comments
EVALUATION Here's a demonstration of a failure with repeated process invocations: $ cat Leak2.java; echo ----; ulimit -Hn 256; jver 6 java -Xms500m -Xmx500m Leak2 public class Leak2 { public static void main(String[] args) throws Throwable { int i = 0; for (i = 0; ; i++) { try { Process p = Runtime.getRuntime().exec("/bin/true"); p.waitFor(); } catch (Throwable t) { System.out.println(i); throw t; } } } } ---- 81 Exception in thread "main" java.io.IOException: Cannot run program "/bin/true": error=24, Too many open files at java.lang.ProcessBuilder.start(ProcessBuilder.java:459) at java.lang.Runtime.exec(Runtime.java:593) at java.lang.Runtime.exec(Runtime.java:431) at java.lang.Runtime.exec(Runtime.java:328) at Leak2.main(Leak2.java:6) Caused by: java.io.IOException: error=24, Too many open files at java.lang.UNIXProcess.forkAndExec(Native Method) at java.lang.UNIXProcess.<init>(UNIXProcess.java:53) at java.lang.ProcessImpl.start(ProcessImpl.java:65) at java.lang.ProcessBuilder.start(ProcessBuilder.java:452) ... 4 more
21-08-2006

EVALUATION Submitter is correct.
21-08-2006