United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
JDK-6462165 : (process) Preach Process file handle hygiene

Details
Type:
Bug
Submit Date:
2006-08-21
Status:
Open
Updated Date:
2011-06-08
Project Name:
JDK
Resolved Date:
Component:
core-libs
OS:
generic
Sub-Component:
java.lang
CPU:
generic
Priority:
P3
Resolution:
Unresolved
Affected Versions:
6
Targeted Versions:

Related Reports
Relates:
Relates:
Relates:
Relates:

Sub Tasks

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

Submitter is correct.
                                     
2006-08-21
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
                                     
2006-08-21



Hardware and Software, Engineered to Work Together