I want to continue the conversation here. I try something else. see below
************************
Hi Sébastien,
A zombie process usually occurs when a process forks a child process, the child process makes the 'exit()' system call and the parent process does not make call 'wait()' on the child process to read the exit status. In Java this can occur if you use ProcesBuilder and the std output buffer of the child process fills up and is not read. Is the application using ProcessBuilder to fork child processes?
************************
yes it's what I'm using.
In my Quarkus application I'm calling a process to Helm to install/update a chart. What should I add to close correctly the sub process ?
String command = "helm install release xxx";
Process pr = Runtime.getRuntime().exec(command);
List<String> lines = IOUtils.readLines(pr.getInputStream(), Charset.defaultCharset());
or
String command = "helm install release xxx";
LOGGER.debug("handle Install request : command [{}]", command);
waitForNormalTermination(Runtime.getRuntime().exec(command), INSTALL_TIMEOUT, TimeUnit.SECONDS, name);
private void waitForNormalTermination(Process process, int timeout, TimeUnit unit, String release) throws Exception {
if (!process.waitFor(timeout, unit)) {
throw new TimeoutException("Timeout while executing " +
process.info().commandLine().orElse(null));
}
if (process.exitValue() != 0) {
String errorStreamOutput = IOUtils.toString(process.getErrorStream(), StandardCharsets.UTF_8);
if (errorStreamOutput != null && errorStreamOutput.contains("release: not found")) {
throw new ReleaseNotFoundException(release);
}
throw new Exception("Process termination was abnormal, exit value: [" + process.exitValue() + "], command:[" +
process.info().commandLine().orElse(null) + "] error returned:[" + errorStreamOutput + "]");
}
}
I have another usecase when I call a powershell script to put labels on pods
import com.profesorfalken.jpowershell.PowerShell;
import com.profesorfalken.jpowershell.PowerShellResponse;
...
try (PowerShell powerShell = PowerShell.openSession()) {
String script = generateScript(scriptContent.toString());
LOGGER.debug("handle add labels to [{}] request : command [{}] with script [{}]", resourceType, command, script);
Map<String, String> config = new HashMap<>();
config.put("maxWait", String.valueOf(TimeUnit.SECONDS.toMillis(DEFAULT_TIMEOUT))); // timeout
PowerShellResponse response = powerShell.configuration(config).executeScript(script);
String commandOutput = response.getCommandOutput();
if (response.isTimeout()) {
throw new TimeoutException("Timeout while executing [" + script + "]");
}
if (response.isError()) {
throw new Exception("Process termination was abnormal, command:[" + script + "] and output was [" + commandOutput + "]");
}
}
*************
I added pr.destroy(); before throwning exceptions and existing my methods just to see if it will change something.
PS. the code that use Process is used only when I'm installing or updating something from my application.. which is not the case right now. So there is no activity like that right now.
Here what I did
#1 - add pr.destroy(); in my code
#1b - build and publish the image
#2 - I killed my pod in my cluster.
#3 - my pod was recreated with the new image
#4 - I look into my node were I had zombies (it's the same where my application was).
I killed the process java that were generating zombie. I had over 12 000 zombies.. now I'm back at 4200.
#5 - I did : ps aux | grep 'Z' | wc -l
in a loop to see if I have new zombies... and yes.. they are still increasing
now I have this : root@test-pcl111:~# ps aux | grep 'Z' | wc -l
4487
I did this : kubectl logs iep-iep-codec-staging-7596fccd85-jkn68 --follow
in another terminal so see if I have activities...
the zombies are still increasing each 1-2 seconds even when I don't have activity on my side other than few periodics REST calls (polling from others applications).
Did a miss something ?