Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

High CPU load in sub-child process

I'm working on a java program that run a batch file using a ProcessBuilder.

public class Test {

    public static void main(String[] args){
        try {
            ProcessBuilder processBuilder = new ProcessBuilder("pathToMyBatch.bat");
            Process process = processBuilder.start();
            StreamReader fluxSortie = new StreamReader(process.getInputStream());
            StreamReader fluxErreur = new StreamReader(process.getErrorStream());
            new Thread(fluxSortie).start();
            new Thread(fluxErreur).start();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    static class StreamReader implements Runnable {

        private final InputStream inputStream;

        StreamReader(InputStream inputStream) {
            this.inputStream = inputStream;
        }

        private BufferedReader getBufferedReader(InputStream is) {
            return new BufferedReader(new InputStreamReader(is));
        }

        @Override
        public void run() {
            BufferedReader br = getBufferedReader(inputStream);
            String ligne = "";
            try {
                while ((ligne = br.readLine()) != null) {
                    System.out.println(ligne);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}

StreamReader class is a Runnablethat wait for inputs and print every read line.

Thebatch file launches an other java application simply by calling java -classpath..., and do other stuff related (and unrelated) to this application.

I can't modify this batch.

To make it clear: Program A launches batch file B that launches application C

When I run the batch file B directly from windows, the java application C barely use more than 2% of CPU. But when I run it through my java program A, C consumes 25% of CPU load (1 full core). In both cases, the batch execution charge on CPU is ~0%.

I guess that's due to the output and error streams of the java application that are not handled correctly.

Am I right? How could I fix this? Is there any way to get the sub-child (the child of the process) process stream?

like image 784
jhamon Avatar asked Nov 10 '22 06:11

jhamon


1 Answers

I guess that's due to the output and error streams of the java application that are not handled correctly.

Am I right?

Possibly. But that is a very vague description of what (you think) is happening.

I suspect that the problem is in your StreamReader class. For example:

  • it could be reading the stream without buffering,
  • it could be polling the stream,
  • it could be processing (or accumulating) the output in an inefficient way,
  • or something else.

If you want a better answer, we really need to see the code of that class.


I suspect that it is the System.out.println calls.

Or perhaps it is that the child Java application is writing its output without buffering.

like image 187
Stephen C Avatar answered Nov 15 '22 11:11

Stephen C