Java 的 Runtime 类

一、简述

Java Runtime 类提供了许多的 API 来与 Java runtime environment 进行交互,如:

  1. 执行一个进程。
  2. 调用垃圾回收。
  3. 查看总内存和剩余内存。

类注释:

/**
 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. 
每个java应用有单个类Runtime实例【让我想起了单例】,这允许应用
去和应用正在运行的环境交互。

The current runtime can be obtained from the getRuntime method.
当前的runtime对象能够从getRuntime()方法中获得。
 
An application cannot create its own instance of this class.
应用程序本身不能创建这个类(Runtime)的实例
 
 @author  unascribed
 @see     java.lang.Runtime#getRuntime()
 @since   JDK1.0
 */

二、类代码

Runtime 是单例的,可以通过Runtime.getRuntime()得到这个单例。常见方法列举:

1️⃣拥有一个静态初始化对象——饿汉模式。

private static Runtime currentRuntime = new Runtime();

2️⃣getRuntime()

/**
Returns the runtime object associated with the current Java application.
返回与当前Java应用关联的runtime对象。

Most of the methods of class Runtime are instance methods and 
must be invoked with respect to the current runtime object.
大多数Runtime类的方法是实例方法,所以必须被当前运行时对象调用。

 @return the Runtime object associated with the current Java application.
 */
public static Runtime getRuntime () {
    return currentRuntime;
}

3️⃣availableProcessors()

/**
 Returns the number of processors available to the Java virtual machine.
 返回Java虚拟机可用的处理器数。

 This value may change during a particular invocation of the virtual machine.
Applications that are sensitive to the number of available processors should 
therefore occasionally poll this property and 
adjust their resource usage appropriately.

 @return the maximum number of processors available to the virtual machine;
never smaller than one
 @since 1.4
 */
public native int availableProcessors ();

4️⃣exec(String command)

/**
 Executes the specified string command in a separate process.
 在一个单独的进程中执行指定的命令。

This is a convenience method.
这是一个方便的方法。

An invocation of the form exec(command) behaves in exactly the same way as the invocation  
#exec(String, String[], File) exec(command, null, null).
以exec(command)形式调用与exec(String,Stringp[],file)的表现是相同的。

 @param   command   a specified system command.
【参数:一个指定的系统命令】

 @return A new Process object for managing the subprocess
【返回值:一个新的用于管理子进程的的Process对象】

 @throws SecurityException
 If a security manager exists and its
 {@link SecurityManager#checkExec checkExec}
 method doesn't allow creation of the subprocess

 @throws IOException
 If an I/O error occurs

 @throws NullPointerException
 If <code>command</code> is <code>null</code>

 @throws IllegalArgumentException
 If <code>command</code> is empty

 @see     #exec(String[], String[], File)
 @see     ProcessBuilder
 */
public Process exec (String command) throws IOException {
    return exec(command, null, null);
}

三、测试

public class MemoryDemo {
    public static void main(String[] args) {

        System.out.println("-----Runtime类描述了虚拟机一些信息-----");
        Runtime runtime = Runtime.getRuntime();
        System.out.println("总内存:" + runtime.totalMemory() / (1024 * 1024) + " M");
        System.out.println("最大内存:" + runtime.maxMemory() / (1024 * 1024) + " M");
        System.out.println("剩余内存:" + runtime.freeMemory() / (1024 * 1024) + " M");
        System.out.println("最大可用内存: " + getUsableMemory());
        System.out.println("处理器个数: " + runtime.availableProcessors());
        for (int i = 0; i < 10000; i++) {
            new Object();
        }
        System.out.println("创建10000个实例之后, 剩余内存: " + runtime.freeMemory() / (1024 * 1024) + " M");

        System.out.println("-----Runtime类提供gc(),用于释放JVM的无用空间-----");
        runtime.gc();
        System.out.println("gc之后, 剩余内存: " + runtime.freeMemory() / (1024 * 1024) + " M");

        System.out.println("-----Runtime类可以调用本机的一些可执行程序,并且创建进程。exec(String cmd)可以打开一个可执行程序-----");
        //下面代码演示了打开windows记事本程序并5秒后关闭。
        Process process = null;
        try {
            process = runtime.exec("notepad");
            Thread.sleep(1000 * 5);
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        } finally {
            process.destroy();
        }

        System.out.println("-----注册钩子线程-----");
        try {
            runtime.addShutdownHook(new Thread(() -> System.out.println("programming exit!")));
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("注册钩子线程over");

        System.out.println("-----取消注册钩子线程-----");
        try {
            Thread thread = new Thread(() -> System.out.println("programming exit!"));
            runtime.addShutdownHook(thread);
            Thread.sleep(3000);
            Runtime.getRuntime().removeShutdownHook(thread);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("取消注册钩子线程over");

        System.out.println("-----退出程序-----");
        Runtime.getRuntime().exit(0);
        //如下代码不会被执行
        System.out.println("Program Running Check");
    }

    /**
     * 获得JVM最大可用内存 = 最大内存-总内存+剩余内存
     */
    private static long getUsableMemory() {
        Runtime r = Runtime.getRuntime();
        return (r.maxMemory() - r.totalMemory() + r.freeMemory()) / (1024 * 1024);
    }
}

system.exit(0) 和 system.exit(1)

推荐阅读更多精彩内容