javapythonprocessbuildermemory-consumptioncpu-time

How do I get the memory usage and cpu time of a process executed using ProcessBuilder?


I am executing python/perl scripts on java using processBuilder. I want to know the memory usage and CPU time for the process executed. Java mx bean is limited to jvm. Hence ,I don't think it can be used for script executions. Please help.


Solution

  • If you are using Java 9 or later, use Process::info() to get the ProcessHandle.Info object for the process (if available). Depending on what the JVM supports on your OS platform, that may give you the total CPU time for the process, and the processes start time ... which you can use to calculate the elapsed time, under some circumstances.


    Another alternative on a Linux system is to execute the command as "/usr/bin/time your command", and parse the last three lines of standard output to get the elapsed time, "user" CPU time and "system" CPU time.

    For example:

    $ time date
    Thu Jul  5 20:25:01 AEST 2018
    
    real    0m0.002s
    user    0m0.001s
    sys     0m0.001s
    

    Capture and parse the last 3 lines. (Implementing this in Java is left as an exercise ...)

    The GNU version of the time command has options that can be used to show memory usage as well. This is described in the manual entry.

    Some equivalent commands for Windows are described here:


    For the record, this (roughly speaking) is the way use time using ProcessBuilder:

       ProcessBuilder pb = new ProcessBuilder(
               "sh", "-c", "/usr/bin/time python filename.py");
    

    or

       ProcessBuilder pb = new ProcessBuilder(
               "/usr/bin/time python filename.py");
    

    If you are going to run commands in a subshell using "sh -c", the shell input string must be a single command argument. Since ProcessBuilder doesn't understand quoting, this means that you must do the splitting yourself; see above.

    To get the GNU time to output the memory parameters, you need to use a format string, as described in "man time"; e.g.

      /usr/bin/time -f "%e %s %u %M" command to be run
    

    Note that it is important to use "/usr/bin/time" rather than "time", since the builtin "time" command in some shells doesn't understand the "-f" option.