<defunct> processes

G

Gordon Beaton

I've got a problem with <defunct> (zombie) processes on Linux...

I had the idea to detect if the process has stucked, and then try
from another thread to Process.destroy(), but it didn't help!

No, because defunct processes are not really processes (anymore),
they're just entries in the process table.
Newsgroups and web are full of similar questions, but no answer.
They all say that a process is zombie if it is finished, but parent
process hasn't yet read the exit code.

That's exactly what they are.
But I do read exitValue,

If you have succesfully read the exit code, then the JVM has called
the proper system calls and the child process should be cleaned up by
the OS kernel. That seems to indicate that these defunct processes are
in fact not direct descendents of the JVM, but rather "grandchildren"
started by your child process, and that the bug is with the child
process.

/gordon
 
L

Lovro

I've got a problem with <defunct> (zombie) processes on Linux...

I'm running child processes using Runtime.exec() and it usually goes well.
But just sometimes (undefined sometimes), process finishes as defunct. Is
there anything I can do about it? I suck out both inputStream and
errorStream, check Process.exitValue(), but it stucks on Process.waitFor().
I even try to suck these streams in separate threads, but it doesn't help.

I had the idea to detect if the process has stucked, and then try from
another thread to Process.destroy(), but it didn't help! Destroy does
nothing, process is still defunct, and waitFor() blocks it again... There
are no more methods in class Process to try, and I've already tried all the
combinations of existing ones...

Newsgroups and web are full of similar questions, but no answer. They all
say that a process is zombie if it is finished, but parent process hasn't
yet read the exit code. But I do read exitValue, and I also do
Process.waitFor(). Can I consider this a bug in Java VM?

Where could find the solution? Which direction should I go? I've been trying
for months, but no results...

Now, this is the latest version of code, as seen on java.sun.com...

{
....
Process process = Runtime.getRuntime().exec(commandLine);
inputVacuum = new TextVacuum(process.getInputStream());
errorVacuum = new TextVacuum(process.getErrorStream());

process.waitFor();

int exitValue = process.exitValue();
....
}


public class TextVacuum extends Thread {

private BufferedReader reader;
private StringBuffer buffer = new StringBuffer();

....

public TextVacuum(InputStream inStream) {
reader = new BufferedReader(new InputStreamReader(inStream));
start();
}


public void run() {
try {
char[] cbuf = new char[4096];
int numRead = reader.read(cbuf);
while (numRead != -1) {
buffer.append(new String(cbuf, 0, numRead));
numRead = reader.read(cbuf);
}
}
catch (IOException e) { }
finally {
try { reader.close(); }
catch (IOException e) { }
reader = null;
}
}

....
}

Thanks!
 
L

Lovro

That seems to indicate that these defunct processes are
in fact not direct descendents of the JVM, but rather "grandchildren"
started by your child process

I'm calling ping and nmap processes that shouldn't make their own
subprocesses...
If you have succesfully read the exit code, then the JVM has called
the proper system calls and the child process should be cleaned up by
the OS kernel.

When the described happens, process is <defunct>:

process.destroy() does nothing...

process.exitValue() throws IllegalThreadStateException which means it
hasn't finished yet. The same says process.waitFor() in its own way,
it waits...

Java thinks that process is not finished, Linux thinks it is. Java
won't read exitValue until the process is finished, and Linux won't
dispose the process before the parent reads its exitValue!!!!!!!!

Something weird is going on. Looks more like a system or JVM problem
to me.
 
J

John C. Bollinger

Lovro said:
I'm calling ping and nmap processes that shouldn't make their own
subprocesses...

Rather than assume, it might be a good idea to check the process list to
see. For every process you can get that process' number _and_ its
parent process' number. Look for other processes with your defunct
process' number as their parent process number; normally these will have
higher numbers than the parent's.


John Bollinger
(e-mail address removed)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top