Friday 17 March 2017

Process, Runtime & System - Java Tutorials

Process

The abstract Process class encapsulates a process—that is, an executing program. It is used primarily as a superclass for the type of objects created by exec( ) in the Runtime class described in the next section.


The Abstract Methods Defined by Process

void destroy( ):  Terminates the process.

int exitValue( ):  Returns an exit code obtained from a subprocess.

InputStream getErrorStream( ):  Returns an input stream that reads input from the process’ err output stream.

InputStream getInputStream( ):  Returns an input stream that reads input from the process’ out output stream.

OutputStream getOutputStream( ):  Returns an output stream that writes output to the process’ in input stream.

int waitFor( ) throws InterruptedException:  Returns the exit code returned by the process. This method does not return until the process on which it is called terminates.




Runtime

The Runtime class encapsulates the run-time environment. You cannot instantiate a Runtime object. However, you can get a reference to the current Runtime object by calling the static method Runtime.getRuntime( ). Once you obtain a reference to the current Runtime object, you can call several methods that control the state and behavior of the Java Virtual Machine. Applets and other untrusted code typically cannot call any of the Runtime methods without raising a SecurityException.
Java 2 deprecates the method runFinalizersOnExit( ). This method was added by Java 1.1 but was deemed unstable.


The Commonly Used Methods Defined by Runtime

void addShutdownHook(Thread thrd):  Registers thrd as a thread to be run when the Java virtual machine terminates. (Added by Java 2, version 1.3)

Process exec(String progName) throws IOException:  Executes the program specified by progName as a separate process. An object of type Process is returned that describes the new process.

Process exec(String progName, tring environment[ ]) throws IOException:   Executes the program specified by progName as a separate process with the environment specified by environment. An object of type Process is returned that describes the new process.

Process exec(String comLineArray[ ]) throws IOException:   Executes the command line specified by
the strings in comLineArray as a separate process. An object of type Process is returned that describes the new process.

Process exec(String comLineArray[ ], String environment[ ]) throws IOException:  Executes the command line specified by the strings in comLineArray as a separate process with the environment specified by environment. An object of type Process is returned that describes the new process.

void exit(int exitCode):  Halts execution and returns the value of exitCode to the parent process. By convention, 0 indicates normal termination. All other values indicate some form of error.

long freeMemory( ):  Returns the approximate number of bytes of free memory available to the Java
run-time system.

void gc( ):  Initiates garbage collection.

static Runtime getRuntime( ):  Returns the current Runtime object.

void halt(int code):  Immediately terminates the Java virtual machine. No termination threads or
finalizers are run. The value of code is returned to the invoking process. (Added by Java 2, version 1.3)

void load(String libraryFileName):  Loads the dynamic library whose file is specified by libraryFileName, which must specify its complete path.

void loadLibrary(String libraryName):  Loads the dynamic library whose name is associated with libraryName.

boolean removeShutdownHook(Thread thrd):  Removes thrd from the list of threads to run when the Java virtual machine terminates. It returns true if successfulthat is, if the thread was removed. (Added by Java 2, verison 1.3)

void runFinalization( ):  Initiates calls to the finalize( ) methods of unused but not yet recycled objects.

long totalMemory( ):  Returns the total number of bytes of memory available to the program.

void traceInstructions(boolean traceOn):  Turns on or off instruction tracing, depending upon the value of traceOn. If traceOn is true, the trace is displayed. If it is false, tracing is turned off.

void traceMethodCalls(boolean traceOn):  Turns on or off method call tracing, depending upon the value of traceOn. If traceOn is true, the trace is displayed. If it is false, tracing is turned off.


Let’s look at two of the most common uses of the Runtime class: memory management and executing additional processes.


Memory Management

Although Java provides automatic garbage collection, sometimes you will want to know how large the object heap is and how much of it is left. You can use this information, for example, to check your code for efficiency or to approximate how many more objects of a certain type can be instantiated. To obtain these values, use the totalMemory( ) and freeMemory( ) methods.

As we mentioned in Part I, Java’s garbage collector runs periodically to recycle unused objects. However, sometimes you will want to collect discarded objects prior to the collector’s next appointed rounds. You can run the garbage collector on demand by alling the gc( ) method. A good thing to try is to call gc( ) and then call freeMemory( ) to get a baseline memory usage. Next, execute your code and call freeMemory( ) again to see how much memory it is allocating. The following program illustrates this idea:

  // Demonstrate totalMemory(), freeMemory() and gc().
  
  class MemoryDemo {
    public static void main(String args[]) {
      Runtime r = Runtime.getRuntime();
      long mem1, mem2;
      Integer someints[] = new Integer[1000];

      System.out.println("Total memory is: " +
                         r.totalMemory());

      mem1 = r.freeMemory();
      System.out.println("Initial free memory: " + mem1);
      r.gc();
      mem1 = r.freeMemory();
      System.out.println("Free memory after garbage collection: "
                         + mem1);

      for(int i=0; i<1000; i++)
        someints[i] = new Integer(i); // allocate integers

      mem2 = r.freeMemory();
      System.out.println("Free memory after allocation: "
                         + mem2);
      System.out.println("Memory used by allocation: "
                         + (mem1-mem2));

      // discard Integers
      for(int i=0; i<1000; i++) someints[i] = null;

      r.gc(); // request garbage collection

      mem2 = r.freeMemory();
      System.out.println("Free memory after collecting" +
                         " discarded Integers: " + mem2);
    }
  }

Sample output from this program is shown here (of course, your actual results may vary):

  Total memory is: 1048568
  Initial free memory: 751392
  Free memory after garbage collection: 841424
  Free memory after allocation: 824000
  Memory used by allocation: 17424
  Free memory after collecting discarded Integers: 842640


Executing Other Programs

In safe environments, you can use Java to execute other heavyweight processes (that is, programs) on your multitasking operating system. Several forms of the exec( ) method allow you to name the program you want to run as well as its input parameters. The exec( ) method returns a Process object, which can then be used to control how your Java program interacts with this new running process. Because Java can run on a variety of platforms and under a variety of operating systems, exec( ) is inherently environment-dependent.

The following example uses exec( ) to launch notepad, Windows’ simple text editor. Obviously, this example must be run under the Windows operating system.

  // Demonstrate exec().
  class ExecDemo {
    public static void main(String args[]) {
      Runtime r = Runtime.getRuntime();
      Process p = null;

      try {
        p = r.exec("notepad");
      } catch (Exception e) {
        System.out.println("Error executing notepad.");
      }
    }
  }

There are several alternate forms of exec( ), but the one shown in the example is the most common. The Process object returned by exec( ) can be manipulated by Process’ methods after the new program starts running. You can kill the subprocess with the destroy( ) method. The waitFor( ) method causes your program to wait until the subprocess finishes. The exitValue( ) method returns the value returned by the subprocess when it is finished. This is typically 0 if no problems occur. Here is the preceding exec( ) example modified to wait for the running process to exit:

  // Wait until notepad is terminated.
  class ExecDemoFini {
    public static void main(String args[]) {
      Runtime r = Runtime.getRuntime();
      Process p = null;

      try {
        p = r.exec("notepad");
        p.waitFor();
      } catch (Exception e) {
        System.out.println("Error executing notepad.");
      }
      System.out.println("Notepad returned " + p.exitValue());
    }
  }

While a subprocess is running, you can write to and read from its standard input and output. The getOutputStream( ) and getInputStream( ) methods return the handles to standard in and out of the subprocess.




System

The System class holds a collection of static methods and variables. The standard input, output, and error output of the Java run time are stored in the in, out, and err variables. The methods defined by System are shown in Table 14-11. Many of the methods throw a SecurityException if the operation is not permitted by the security manager. One other point: Java 2 deprecated the method runFinalizersOnExit( ). This method was added by Java 1.1, but was determined to be unstable. Let’s look at some common uses of System.


The Methods Defined by System

static void arraycopy(Object source, int sourceStart, Object target, int targetStart, int size):  Copies an array. The array to be copied is passed in source, and the index at which point the copy will begin within source is passed in sourceStart. The array that will receive the copy is passed in target, and the index at which point the copy will begin within target is passed in targetStart. size is the number of elements that are copied.

static long currentTimeMillis( ):  Returns the current time in terms of milliseconds since midnight, January 1, 1970.

static void exit(int exitCode):  Halts execution and returns the value of exitCode to the parent process (usually the operating system). By convention, 0 indicates normal termination. All other values indicate some form of error.

static void gc( ):  Initiates garbage collection.

static Properties getProperties( ):  Returns the properties associated with the Java run-time system. (The Properties class is described in Chapter 15.)

static String getProperty(String which):  Returns the property associated with which. A null object is returned if the desired property is not found.

static String getProperty(String which, String default):   Returns the property associated with which. If the desired property is not found, default is returned.

static SecurityManager getSecurityManager( ):  Returns the current security manager or a null object if no security manager is installed.

static int identityHashCode(Object obj):  Returns the identity hash code for obj.

static void load(String libraryFileName):  Loads the dynamic library whose file is specified by libraryFileName, which must specify its complete path.

static void loadLibrary(String libraryName):  Loads the dynamic library whose name is associated with libraryName.

static String mapLibraryName(String lib):  Returns a platform-specific name for the library named lib. (Added by Java 2)

static void runFinalization( ):  Initiates calls to the finalize( ) methods of unused but not yet recycled objects.

static void setErr(PrintStream eStream):  Sets the standard err stream to eStream.

static void setIn(InputStream iStream):  Sets the standard in stream to iStream.

static void setOut(PrintStream oStream):  Sets the standard out stream to oStream.

static void setProperties(Properties sysProperties):  Sets the current system properties as specified by sysProperties.

static String setProperty(String which, String v):  Assigns the value v to the property named which. (Added by Java 2)

static void setSecurityManager(SecurityManager secMan):   Sets the security manager to that specified by secMan.


Using currentTimeMillis( ) to Time Program Execution

One use of the System class that you might find particularly interesting is to use the currentTimeMillis( ) method to time how long various parts of your program take to execute. The currentTimeMillis( ) method returns the current time in terms of milliseconds since midnight, January 1, 1970. To time a section of your program, store this value just before beginning the section in question. Immediately upon completion, call currentTimeMillis( ) again. The elapsed time will be the ending time minus the starting time. The following program demonstrates this:

  // Timing program execution.

  class Elapsed {
    public static void main(String args[]) {
      long start, end;

      System.out.println("Timing a for loop from 0 to 1,000,000");

      // time a for loop from 0 to 1,000,000
      start = System.currentTimeMillis(); // get starting time
      for(int i=0; i < 1000000; i++) ;
      end = System.currentTimeMillis(); // get ending time
      
      System.out.println("Elapsed time: " + (end-start));
    }
  }

Here is a sample run (remember that your results probably will differ):

  Timing a for loop from 0 to 1,000,000
  Elapsed time: 10


Using arraycopy( )

The arraycopy( ) method can be used to copy quickly an array of any type from one place to another. This is much faster than the equivalent loop written out longhand in Java. Here is an example of two arrays being copied by the arraycopy( ) method. First, a is copied to b. Next, all of a’s elements are shifted down by one. Then, b is shifted up by one.

  // Using arraycopy().

  class ACDemo {
    static byte a[] = { 65, 66, 67, 68, 69, 70, 71, 72, 73, 74 };
    static byte b[] = { 77, 77, 77, 77, 77, 77, 77, 77, 77, 77 };

    public static void main(String args[]) {
      System.out.println("a = " + new String(a));
      System.out.println("b = " + new String(b));
      System.arraycopy(a, 0, b, 0, a.length);
      System.out.println("a = " + new String(a));
      System.out.println("b = " + new String(b));
      System.arraycopy(a, 0, a, 1, a.length - 1);
      System.arraycopy(b, 1, b, 0, b.length - 1);
      System.out.println("a = " + new String(a));
      System.out.println("b = " + new String(b));
    }
  }

As you can see from the following output, you can copy using the same source and destination in either direction:

  a = ABCDEFGHIJ
  b = MMMMMMMMMM
  a = ABCDEFGHIJ
  b = ABCDEFGHIJ
  a = AABCDEFGHI
  b = BCDEFGHIJJ


Environment Properties

The following properties are available in Java 2, version 1.4:

file.separator                      java.specification.version                   java.vm.version
java.class.path                    java.vendor                                         line.separator
java.class.version               java.vendor.url                                    os.arch
java.compiler                     java.version                                         os.name
java.ext.dirs                        java.vm.name                                      os.version
java.home                           java.vm.specification.name                path.separator
java.io.tmpdir                     java.vm.specification.vendor              user.dir
java.library.path                  java.vm.specification.version             user.home
java.specification.name      java.vm.vendor                                    user.name
java.specification.vendor

You can obtain the values of various environment variables by calling the System.getProperty( ) method. For example, the following program displays the path to the current user directory:

  class ShowUserDir {
    public static void main(String args[]) {
      System.out.println(System.getProperty("user.dir"));
    }
  }