|
Quick Lists
|
|
Bug ID:
|
4784692
|
|
Votes
|
1
|
|
Synopsis
|
(process) Process.waitFor does not release resources
|
|
Category
|
java:classes_lang
|
|
Reported Against
|
1.3
, mantis
|
|
Release Fixed
|
|
|
State
|
11-Closed,
Will Not Fix,
bug
|
|
Priority:
|
2-High
|
|
Related Bugs
|
4637504
,
4801027
,
4781460
|
|
Submit Date
|
26-NOV-2002
|
|
Description
|
Alexey Gibadullin, xxxxx@xxxxx
While working on the bug
4637504 (process) REGRESSION: java.lang.Process does not clean up file
resources
I have extended Test.java from the bugreport to Test2.java
public class Test2 {
public static void main(String argv[]) {
int threads = Integer.parseInt(argv[0]);
int processes = Integer.parseInt(argv[1]);
for (int i = 0; i < threads; i++)
(new MyThread(i, processes)).start();
}
}
class MyThread extends Thread {
private int number;
private int processes;
MyThread(int n, int p) {
number = n;
processes = p;
}
public void run() {
for (int i = 0; i < processes; i++) {
try {
Runtime runtime = Runtime.getRuntime();
Process process = runtime.exec("echo " + i);
process.waitFor();
} catch (Exception e) {
System.out.println("Thread " + number + " got " + e);
e.printStackTrace(System.out);
return;
}
System.out.println("Thread " + number + ". Process " + i);
}
}
}
Test2 reveals that the bug #4637504 still present in Mantis-b07, if processes
are executed from a thread (4637504 was integrated into hopper).
% uname -a
SunOS novo152 5.8 Generic_108528-16 sun4u sparc SUNW,Ultra-5_10
% ../jdk1.4.2-b07/solaris-sparc/bin/java Test2 1 400
Thread 0. Process 0
Thread 0. Process 1
Thread 0. Process 2
...
Thread 0. Process 334
Thread 0. Process 335
Thread 0. Process 336
Thread 0. Process 337
Thread 0 got java.io.IOException: Too many open files
java.io.IOException: Too many open files
at java.lang.UNIXProcess.forkAndExec(Native Method)
at java.lang.UNIXProcess.<init>(UNIXProcess.java:54)
at java.lang.Runtime.execInternal(Native Method)
at java.lang.Runtime.exec(Runtime.java:566)
at java.lang.Runtime.exec(Runtime.java:428)
at java.lang.Runtime.exec(Runtime.java:364)
at java.lang.Runtime.exec(Runtime.java:326)
at MyThread.run(Test2.java:24)
You may also increase number of threads. java.io.IOException is also thrown,
but it needs less number of processes:
% ../jdk1.4.2-b07/solaris-sparcv9/bin/java -d64 -server Test2 3 200
Thread 0. Process 0
Thread 1. Process 0
Thread 2. Process 0
Thread 0. Process 1
Thread 1. Process 1
Thread 2. Process 1
Thread 2. Process 2
Thread 0. Process 2
...
Thread 0. Process 108
Thread 1. Process 107
Thread 2. Process 110
Thread 0. Process 109
Thread 1. Process 108
Thread 2. Process 111
Thread 2. Process 112
Thread 0. Process 110
Thread 1. Process 109
Thread 2. Process 113
Thread 0. Process 111
Thread 1. Process 110
Thread 0 got java.io.IOException: Too many open files
java.io.IOException: Too many open files
at java.lang.UNIXProcess.forkAndExec(Native Method)
at java.lang.UNIXProcess.<init>(UNIXProcess.java:54)
at java.lang.Runtime.execInternal(Native Method)
at java.lang.Runtime.exec(Runtime.java:566)
at java.lang.Runtime.exec(Runtime.java:428)
at java.lang.Runtime.exec(Runtime.java:364)
at java.lang.Runtime.exec(Runtime.java:326)
at MyThread.run(Test2.java:24)
Thread 1 got java.io.IOException: Too many open files
java.io.IOException: Too many open files
at java.lang.UNIXProcess.forkAndExec(Native Method)
at java.lang.UNIXProcess.<init>(UNIXProcess.java:54)
at java.lang.Runtime.execInternal(Native Method)
at java.lang.Runtime.exec(Runtime.java:566)
at java.lang.Runtime.exec(Runtime.java:428)
at java.lang.Runtime.exec(Runtime.java:364)
at java.lang.Runtime.exec(Runtime.java:326)
at MyThread.run(Test2.java:24)
Thread 2. Process 114
Thread 2 got java.io.IOException: Too many open files
java.io.IOException: Too many open files
at java.lang.UNIXProcess.forkAndExec(Native Method)
at java.lang.UNIXProcess.<init>(UNIXProcess.java:54)
at java.lang.Runtime.execInternal(Native Method)
at java.lang.Runtime.exec(Runtime.java:566)
at java.lang.Runtime.exec(Runtime.java:428)
at java.lang.Runtime.exec(Runtime.java:364)
at java.lang.Runtime.exec(Runtime.java:326)
at MyThread.run(Test2.java:24)
The test fails on Solsparc and Solsparcv9 (5.8) and passes
on Windows2000, Linux Red Hat 7.2, Solx86 (5.8), Solsparc and Solsparcv9 (5.9).
======================================================================
Alexey Gibadullin, xxxxx@xxxxx
If I add
process.destroy();
after
process.waitFor();
the test passes fine even on Solsparc 5.8. However, the spec for
java.lang.Process says:
public abstract int waitFor() throws InterruptedException
causes the current thread to wait, if necessary, until the process
represented by this Process customer has terminated. This method returns
immediately if the subprocess has already terminated. If the subprocess
has not yet terminated, the calling thread will be blocked until the
subprocess exits.
public abstract void destroy()
Kills the subprocess. The subprocess represented by this Process customer
is forcibly terminated.
Therefore, if the subprocess exits and waitFor() returns the exit value,
there is no need to call destroy(), since destroy() does nothing but killing
the subprocess.
======================================================================
JCK tests execution fails due to this bug. If JDK1.4.1 (b-21) or
JDK1.4.2 (b-10) is used to run JavaTest harness then a lot of JCK tests
fail in multiJVM mode with "java.io.IOException: Too many open files".
This bug can be observed in case of one thread.
To do this execute following test:
------------- test.java ----------------------
public class test {
public static void main(String argv[]) {
int i = 0;
try {
for(i = 0; i < 100000; i++) {
Process p = Runtime.getRuntime().exec("ls");
}
} catch (java.io.IOException e) {
System.out.println("Iteration: " + i + " Exception: " + e);
}
}
}
------------- log ----------------------------
$javac test.java
$
$java -version
java version "1.4.2-beta"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2-beta-b10)
Java HotSpot(TM) Client VM (build 1.4.2-beta-b10, mixed mode)
$
$uname -a
SunOS novo49 5.8 Generic_108528-15 sun4u sparc SUNW,Ultra-2
$
$java -Xfuture test
Iteration: 338 Exception: java.io.IOException: Too many open files
----------------------------------------------
======================================================================
|
|
Work Around
|
N/A
|
|
Evaluation
|
Will not fix. The current behavior dates back to the rewrite of the Process
code back in 1.2/1.3 which removed the dangerous buffering of all subprocess
output. In order to release all resources, user code must either invoke
Process.destroy or manually close the three subprocess streams.
I've submitted 4801027 to request clarification of the Process spec on this
point.
-- xxxxx@xxxxx 2003/1/9
|
|
Comments
|
Submitted On 18-DEC-2002
rganesan
The related bug fix says that all the streams are closed on
destroy(). The
same needs to happen when you call waitFor() or exitValue()
because
the process is no longer running after a successful call.
This bug definitely does not exist in JDK 1.3.1.
Submitted On 24-FEB-2003
rganesan
FWIW, I don't agree with this resolution. When waitFor() or
exitValue() returns successfully, the process has already
terminated - there is no buffering issue. As mentioned in my
earliser comment, JDK 1.3.1 does
not have this bug.
Submitted On 24-JUN-2004
brozow
Even though you can be sure that the process has terminated with a call to waitFor and exitValue, this does not imply that the JVM has closed the fileDescriptors is has open to received the output generated by the process. This is the reason that we get Too Many Open Files exceptions.
destroy() ensures those file descriptors get closed.
Submitted On 26-JUL-2004
hong.le
I got this error from using ColdFusion MX on Windows2003 version. Wonder if you have tested with this Windows2003 o/s?
Submitted On 16-SEP-2004
syates
Just ran into this myself, in 1.4.2. Why not make it clear in the Javadoc for Process that destroy must be called even after waitFor returns? That didn't seem obvious to me.
PLEASE NOTE: JDK6 is formerly known as Project Mustang
|
|
|
 |