Java – Handles leaks when running external commands from Java

Handles leaks when running external commands from Java… here is a solution to the problem.

Handles leaks when running external commands from Java

When I try to execute an external process, I notice a handle leak in my Java program. My sample code is provided below. Can you guide me on what I did wrong?

I run this program with Open JDK 10 on the Windows 10 operating system. Is there any way to minimize the handle?

import java.util.*;
import java.io.*;

public class Test {

public static void main(String args[]) {
        while (true) {
            Process p = null;
            try {
                 p = new ProcessBuilder("ipconfig").start();
                p = Runtime.getRuntime().exec("cmd /c ipconfig");
                BufferedReader br[] = new BufferedReader[2];
                br[1] = new BufferedReader(new InputStreamReader(p.getErrorStream()));
                br[0] = new BufferedReader(new InputStreamReader(p.getInputStream()));

int errCode = p.waitFor();
                try {
                    br[0].close();
                } catch (Exception a) {}
                try {
                    br[1].close();
                } catch (Exception a) {}
            } catch (Exception grrr) {}

finally {
                try {
                    closeStreams(p);
                    p.destroy();
                } catch (Exception r) {
                }
            }
        }
    }

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

Solution

There seems to be a problem in the operating system (OS) or machine where I am running the program. When I run on another machine with OpenJDK 10 there was no handle leak, but the number of handles increased to a maximum of 2800 and then dropped to 450.

Note the following while experimenting.

  • With Oracle HotSpot JDK 7 and 8, there is no handle leak, even though I only close the input and error streams – (not closing the output stream because I won’t use it in my code) but the same code leaks are handled when using OpenJDK 10.
  • Closing all three streams (input, output, and error) solved the handle leakage issue.

Related Problems and Solutions