Thursday, 9 June 2011

Using the JDK’s Runtime Class

“Every Java application has a single instance of class Runtime that allows the application to interface with the environment in which the application is running” is the brief JavaDoc entry for the JDK’s Runtime class, which, if you examine the methods it contains, doesn’t really cover what this class does. The methods that this class contains can be divided into several categories:
  1. Executing external applications and loading libraries for native method calls.
  2. Debugging methods; including memory checks and enabling detailed output.
  3. Managing shutdown hooks.
Before demonstrating some of these methods, we first need to get hold of a Runtme class instance. This is done using the static factory method:

    Runtime runtime = Runtime.getRuntime();

Using exec to run other Processes

The code below demonstrates how to use the exec() method. Note that I’ve added a Process.waitFor() call as the Java process should wait for the external process to exit before checking its results or disposing of the Process instance.

    try {
     
// The Runtime object can then execute other programs
      // exec returns a Process object that allows us to control
      // the new program
     
Process process = runtime.exec("C:\\Program Files\\WinZip\\WINZIP32.EXE");
     
// It's usual to wait for the process to end before destroying the process object
     
process.waitFor();
     
// destroy the process object
     
process.destroy();
      System.out.println
("The exit value the program is: " + process.exitValue());
   
} catch (Exception e) {
     
e.printStackTrace();
   
}

Memory Methods

The Runtime has three methods for interrogating the JVM’s memory. These are demonstrated below:

    // Display the amount of memory available to the JVM
   
System.out.println("Free Memory is: " + runtime.freeMemory());

   
// Display the total memory that the JVM can use
   
System.out.println("Total Memory is: " + runtime.totalMemory());

   
// Display the max amount memory that the JVM can use
   
System.out.println("Max Memory is: " + runtime.maxMemory());

Debugging Methods

The Runtime class contains a few debugging methods that are supposed to get the JVM to display some debugging information. I’ve never managed to get these to work even though I’ve run a JDK version of the JVM and used the -Xdebug JVM argument as directed by Oracle / Sun. If anyone knows how to make this work, please let me know...

You can trace byte code instructions:

    runtime.traceInstructions(true);
    testMethodCall
("Hello world");
    testMethodCall
("Hello world");
    runtime.traceInstructions
(false);

...and method calls:

    runtime.traceMethodCalls(true);
    testMethodCall
("Hello world again");
    testMethodCall
("Hello world again");
    runtime.traceMethodCalls
(false);

Shutdown Hooks

A shutdown hook is an initialised, but un-started thread that the JVM runs when it’s closing down. The idea is that you can tidy up whatever external resources that you may have open, such as databases etc. Shutdown hooks run in an unspecified order when Runtime.exit() is called.

    // Add a shut down hook - this thread will run when the
    // JVM shuts down. You can add lots of hooks - but the
    // order in which they run is undetermined.
   
runtime.addShutdownHook(new Thread() {
     
@Override
     
public void run() {

       
System.out.println("Shutdown hook running");
     
}
    })
;

To ensure that the shutdown hooks run, use the following code:

    runtime.exit(27); // exit calling shutdown hooks
    // runtime.halt(32); // exit without calling the shutdown hooks

There aren’t really that many uses for this class in everyday programming - except for debugging. Shutdown hooks are useful when closing down Spring context in programs that don’t use a JEE container or Web Server - but more on that another day.

1 comment:

Anonymous said...

Regarding the methods traceInstructions() and traceMethodCalls() : they do not work, this is somehow expected :
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4623283