模块 java.base
 java.lang

类 Runtime

java.lang.Object
java.lang.Runtime

public class Runtime extends Object
每个 Java 应用程序都有一个类 Runtime 的实例,它允许应用程序与应用程序运行的环境进行交互。当前运行时间可以从 getRuntime 方法中获取。

应用程序无法创建自己的此类实例。

关机顺序

Java 虚拟机启动关机顺序响应几个事件之一:

  1. 居住 非守护线程的数量第一次下降到零时(请参阅下面关于 JNI 调用 API 的注释);
  2. 当第一次调用 Runtime.exit System.exit 方法时;或者
  3. 当某些外部事件发生时,例如从操作系统接收到中断或信号。

在关闭序列的开始,注册的关闭挂钩是 started 以某种未指定的顺序。它们与在关闭序列开始时为 的任何守护进程或非守护进程线程同时运行。

关闭序列开始后,禁止使用 addShutdownHook removeShutdownHook 注册和取消注册关闭挂钩。但是,允许创建和启动新线程。新线程与已注册的关闭挂钩以及任何已在运行的守护程序或非守护程序线程同时运行。

当所有关闭挂钩终止时,关闭序列结束。此时,Java 虚拟机如下所述终止。

一个或多个关闭挂钩可能不会终止,例如,由于无限循环。在这种情况下,关机序列永远不会完成。其他线程和关闭挂钩继续运行,并可以通过 halt 方法终止 JVM。

在关闭序列开始之前,程序可以通过显式调用其 start 方法来启动关闭挂钩。如果发生这种情况,则关闭序列的行为是不确定的。

Java 虚拟机终止

JVM 在关闭序列完成或调用 halt 时终止。与 exit 相比,halt 方法不会启动关闭序列。

当 JVM 终止时,所有线程都立即被阻止执行任何进一步的 Java 代码。这包括关闭挂钩以及守护进程和非守护进程线程。这意味着,例如:

  • 线程的当前方法没有正常或突然完成;
  • finally 子句未执行;
  • 未捕获的异常处理程序 未运行;和
  • 使用 try-with-resources 打开的资源不是 关闭
实现注意事项:
本机代码通常使用 JNI 调用 API 来控制 JVM 的启动和终止。这样的本机代码调用 JNI_CreateJavaVM 函数来启动 JVM。随后,本机代码调用 DestroyJavaVM 函数以等待该 JVM 的终止。 DestroyJavaVM 函数负责在 居住 非守护线程的数量首次降至零时启动关闭序列。当关闭序列完成并且 JVM 终止时,控制权返回到调用 DestroyJavaVM 的本机代码。此行为不同于 exit halt 方法。这些方法通常终止托管 JVM 的操作系统进程,并且不与 JNI 调用 API 交互。
Java 语言规范:
12.8 程序退出
自从:
1.0
参见:
  • 方法详情

    • getRuntime

      public static Runtime  getRuntime()
      返回与当前 Java 应用程序关联的运行时对象。 Runtime 类的大部分方法都是实例方法,必须针对当前运行时对象进行调用。
      返回:
      与当前 Java 应用程序关联的 Runtime 对象。
    • exit

      public void exit(int status)
      启动 Java 虚拟机的关机顺序。这种方法无限期地阻塞;它从不返回或抛出异常(也就是说,它不会正常或突然完成)。该参数用作状态代码;按照惯例,非零状态代码表示异常终止。

      此方法的调用是序列化的,因此只有一次调用将实际继续执行关闭序列并终止具有给定状态代码的 VM。所有其他调用只会无限期地阻塞。

      因为此方法总是无限期地阻塞,所以如果从关闭挂钩调用它,它将阻止关闭挂钩终止。因此,这将阻止关闭序列完成。

      System.exit 方法是调用此方法的常规且方便的方法。

      参数:
      status - 终止状态。按照惯例,非零状态代码表示异常终止。
      抛出:
      SecurityException - 如果安全管理器存在且其 checkExit 方法不允许以指定状态退出
      参见:
    • addShutdownHook

      public void addShutdownHook(Thread  hook)
      注册一个新的虚拟机关闭挂钩。

      A 关闭挂钩只是一个初始化但未启动的线程。关闭挂钩在 关机顺序 的开头启动。一旦关闭序列开始,就不允许注册和注销关闭挂钩。

      未捕获的异常在关闭挂钩中处理,就像在任何其他线程中一样,如 Thread.UncaughtExceptionHandler 中指定的那样。未捕获的异常处理程序完成后,关闭挂钩被认为已终止,并且与未抛出未捕获异常而终止的挂钩没有区别对待。

      API 注意:
      关闭挂钩在虚拟机生命周期的微妙时刻运行,因此应该进行防御性编码。特别是,它们应该被编写为线程安全的,并尽可能避免死锁。他们也不应该盲目地依赖可能已经注册了自己的关闭挂钩的服务,因此他们自己可能正在关闭过程中。尝试使用其他基于线程的服务(例如 AWT 事件分发线程)可能会导致死锁。

      关闭挂钩也应该快速完成它们的工作。当程序调用 exit 时,期望虚拟机将立即关闭并退出。当虚拟机由于用户注销或系统关闭而终止时,底层操作系统可能只允许有限的时间来关闭和退出。因此,不建议尝试任何用户交互或在关闭挂钩中执行长时间运行的计算。

      参数:
      hook - 已初始化但未启动的 Thread 对象
      抛出:
      IllegalArgumentException - 如果与指定的钩子相同的钩子(与使用 == 相比)已经注册,或者可以确定该钩子已经运行或已经运行
      IllegalStateException - 如果关机顺序已经开始
      SecurityException - 如果安全管理器存在并且它拒绝 RuntimePermission ("shutdownHooks")
      自从:
      1.3
      参见:
    • removeShutdownHook

      public boolean removeShutdownHook(Thread  hook)
      取消注册先前注册的虚拟机关闭挂钩。使用 == 比较钩子。一旦关闭序列开始,就不允许注册和注销关闭挂钩。
      参数:
      hook - 要删除的挂钩
      返回:
      true 如果指定的挂钩先前已注册并成功注销,false 否则。
      抛出:
      IllegalStateException - 如果关机顺序已经开始
      SecurityException - 如果安全管理器存在并且它拒绝 RuntimePermission ("shutdownHooks")
      自从:
      1.3
      参见:
    • halt

      public void halt(int status)
      立即 terminates Java 虚拟机。终止是无条件和立即的。此方法不会启动 关机顺序 ,如果它已经在进行中,它也不会等待关闭序列完成。此方法永远不会正常返回。
      API 注意:
      应极其谨慎地使用此方法。使用它可能会规避或破坏旨在由关闭挂钩执行的任何清理操作,可能导致数据损坏。有关停止 Java 虚拟机的其他可能后果,请参阅上面的 终止 部分。
      参数:
      status - 终止状态。按照惯例,非零状态代码表示异常终止。如果 exit (等效于 System.exit )方法已被调用,则此状态代码将覆盖传递给该方法的状态代码。
      抛出:
      SecurityException - 如果安全管理器存在且其 checkExit 方法不允许以指定状态退出
      自从:
      1.3
      参见:
    • exec

      @Deprecated (since ="18") public Process  exec(String  command) throws IOException
      已弃用。
      此方法容易出错,不应使用,应使用相应的方法exec(String[]) ProcessBuilder 代替。命令字符串被分解为仅使用空白字符的标记。对于带有嵌入空格的参数,例如文件名,这可能会导致问题,因为令牌不包含完整的文件名。
      在单独的进程中执行指定的字符串命令。

      这是一个方便的方法。 exec(command) 形式的调用与调用 exec (command, null, null) 的行为方式完全相同。

      参数:
      command - 指定的系统命令。
      返回:
      用于管理子流程的新 Process 对象
      抛出:
      SecurityException - 如果安全管理器存在且其 checkExec 方法不允许创建子进程
      IOException - 如果发生 I/O 错误
      NullPointerException - 如果 commandnull
      IllegalArgumentException - 如果 command 为空
      参见:
    • exec

      @Deprecated (since ="18") public Process  exec(String  command, String [] envp) throws IOException
      已弃用。
      此方法容易出错,不应使用,应使用相应的方法exec(String[], String[]) ProcessBuilder 代替。命令字符串被分解为仅使用空白字符的标记。对于带有嵌入空格的参数,例如文件名,这可能会导致问题,因为令牌不包含完整的文件名。
      在具有指定环境的单独进程中执行指定的字符串命令。

      这是一个方便的方法。 exec(command, envp) 形式的调用与调用 exec (command, envp, null) 的行为方式完全相同。

      参数:
      command - 指定的系统命令。
      envp - 字符串数组,其中每个元素都有格式中的环境变量设置name=value或者 null 如果子进程应该继承当前进程的环境。
      返回:
      用于管理子流程的新 Process 对象
      抛出:
      SecurityException - 如果安全管理器存在且其 checkExec 方法不允许创建子进程
      IOException - 如果发生 I/O 错误
      NullPointerException - 如果 commandnull,或者 envp 的元素之一是 null
      IllegalArgumentException - 如果 command 为空
      参见:
    • exec

      @Deprecated (since ="18") public Process  exec(String  command, String [] envp, File  dir) throws IOException
      已弃用。
      这种方法容易出错,不应该使用,应该使用相应的方法exec(String[], String[], File) ProcessBuilder 代替。命令字符串被分解为仅使用空白字符的标记。对于带有嵌入空格的参数,例如文件名,这可能会导致问题,因为令牌不包含完整的文件名。
      在具有指定环境和工作目录的单独进程中执行指定的字符串命令。

      这是一个方便的方法。 exec(command, envp, dir) 形式的调用与调用 exec (cmdarray, envp, dir) 的行为完全相同,其中 cmdarraycommand 中所有标记的数组。

      更准确地说,command 字符串使用由调用 new StringTokenizer(command) 创建的 StringTokenizer 分解为标记,没有进一步修改字符类别。然后,分词器生成的分词以相同的顺序放置在新的字符串数组 cmdarray 中。

      参数:
      command - 指定的系统命令。
      envp - 字符串数组,其中每个元素都有格式中的环境变量设置name=value或者 null 如果子进程应该继承当前进程的环境。
      dir - 子进程的工作目录,如果子进程应继承当前进程的工作目录,则为 null
      返回:
      用于管理子流程的新 Process 对象
      抛出:
      SecurityException - 如果安全管理器存在且其 checkExec 方法不允许创建子进程
      IOException - 如果发生 I/O 错误
      NullPointerException - 如果 commandnull,或者 envp 的元素之一是 null
      IllegalArgumentException - 如果 command 为空
      自从:
      1.3
      参见:
    • exec

      public Process  exec(String [] cmdarray) throws IOException
      在单独的进程中执行指定的命令和参数。

      这是一个方便的方法。 exec(cmdarray) 形式的调用与调用 exec (cmdarray, null, null) 的行为方式完全相同。

      参数:
      cmdarray - 包含要调用的命令及其参数的数组。
      返回:
      用于管理子流程的新 Process 对象
      抛出:
      SecurityException - 如果安全管理器存在且其 checkExec 方法不允许创建子进程
      IOException - 如果发生 I/O 错误
      NullPointerException - 如果 cmdarraynull,或者 cmdarray 的元素之一是 null
      IndexOutOfBoundsException - 如果 cmdarray 是一个空数组(长度为 0
      参见:
    • exec

      public Process  exec(String [] cmdarray, String [] envp) throws IOException
      在具有指定环境的单独进程中执行指定的命令和参数。

      这是一个方便的方法。 exec(cmdarray, envp) 形式的调用与调用 exec (cmdarray, envp, null) 的行为方式完全相同。

      参数:
      cmdarray - 包含要调用的命令及其参数的数组。
      envp - 字符串数组,其中每个元素都有格式中的环境变量设置name=value或者 null 如果子进程应该继承当前进程的环境。
      返回:
      用于管理子流程的新 Process 对象
      抛出:
      SecurityException - 如果安全管理器存在且其 checkExec 方法不允许创建子进程
      IOException - 如果发生 I/O 错误
      NullPointerException - 如果 cmdarraynull ,或者 cmdarray 的元素之一是 null ,或者 envp 的元素之一是 null
      IndexOutOfBoundsException - 如果 cmdarray 是一个空数组(长度为 0
      参见:
    • exec

      public Process  exec(String [] cmdarray, String [] envp, File  dir) throws IOException
      使用指定的环境和工作目录在单独的进程中执行指定的命令和参数。

      给定一个字符串数组 cmdarray ,表示命令行的标记,以及一个字符串数组 envp ,表示“环境”变量设置,此方法创建一个新进程来执行指定的命令。

      此方法检查 cmdarray 是否是有效的操作系统命令。哪些命令有效取决于系统,但至少命令必须是非空字符串的非空列表。

      如果 envpnull ,则子进程继承当前进程的环境设置。

      在某些操作系统上启动进程可能需要一组最小的系统相关环境变量。因此,子流程可能会继承指定环境之外的其他环境变量设置。最小的系统相关环境变量集可能会覆盖环境中提供的值。

      ProcessBuilder.start() 现在是使用修改后的环境启动进程的首选方式。

      新子进程的工作目录由 dir 指定。如果 dirnull ,则子进程继承当前进程的当前工作目录。

      如果存在安全管理器,则调用其 checkExec 方法,并将数组 cmdarray 的第一个组件作为其参数。这可能会导致抛出 SecurityException

      启动操作系统进程高度依赖于系统。许多可能出错的事情包括:

      • 找不到操作系统程序文件。
      • 访问程序文件被拒绝。
      • 工作目录不存在。

      在这种情况下,将抛出异常。异常的确切性质取决于系统,但它始终是 IOException 的子类。

      如果操作系统不支持创建进程,则会抛出一个UnsupportedOperationException

      参数:
      cmdarray - 包含要调用的命令及其参数的数组。
      envp - 字符串数组,其中每个元素都有格式中的环境变量设置name=value或者 null 如果子进程应该继承当前进程的环境。
      dir - 子进程的工作目录,如果子进程应继承当前进程的工作目录,则为 null
      返回:
      用于管理子流程的新 Process 对象
      抛出:
      SecurityException - 如果安全管理器存在且其 checkExec 方法不允许创建子进程
      UnsupportedOperationException - 如果操作系统不支持创建进程。
      IOException - 如果发生 I/O 错误
      NullPointerException - 如果 cmdarraynull ,或者 cmdarray 的元素之一是 null ,或者 envp 的元素之一是 null
      IndexOutOfBoundsException - 如果 cmdarray 是一个空数组(长度为 0
      自从:
      1.3
      参见:
    • availableProcessors

      public int availableProcessors()
      返回 Java 虚拟机可用的处理器数量。

      该值可能会在虚拟机的特定调用期间发生变化。因此,对可用处理器数量敏感的应用程序应偶尔轮询此属性并适当调整其资源使用情况。

      返回:
      虚拟机可用的最大处理器数;从不小于一
      自从:
      1.4
    • freeMemory

      public long freeMemory()
      返回 Java 虚拟机中的可用内存量。调用 gc 方法可能导致增加 freeMemory. 返回的值
      返回:
      当前可用于未来分配对象的内存总量的近似值,以字节为单位。
    • totalMemory

      public long totalMemory()
      返回 Java 虚拟机中的内存总量。此方法返回的值可能会随时间变化,具体取决于主机环境。

      请注意,保存任何给定类型的对象所需的内存量可能取决于实现。

      返回:
      当前和未来对象当前可用的内存总量,以字节为单位。
    • maxMemory

      public long maxMemory()
      返回 Java 虚拟机将尝试使用的最大内存量。如果没有固有限制,则将返回值 Long.MAX_VALUE
      返回:
      虚拟机将尝试使用的最大内存量,以字节为单位
      自从:
      1.4
    • gc

      public void gc()
      在 Java 虚拟机中运行垃圾收集器。

      调用此方法表明 Java 虚拟机努力回收未使用的对象,以使它们当前占用的内存可供 Java 虚拟机重用。当控制从方法调用返回时,Java 虚拟机已尽最大努力从所有未使用的对象中回收空间。无法保证此工作将回收任何特定数量的未使用对象,回收任何特定数量的空间,或在任何特定时间完成,如果有的话,在方法返回之前或永远。也不能保证这种努力将决定任何特定数量的对象的可达性的变化,或者任何特定数量的 Reference 对象将被清除和排队。

      名称 gc 代表“垃圾收集器”。 Java 虚拟机根据需要在单独的线程中自动执行此回收过程,即使未显式调用 gc 方法也是如此。

      System.gc() 方法是调用此方法的常规且方便的方法。

    • runFinalization

      @Deprecated (since ="18", forRemoval =true) public void runFinalization()
      已弃用,将被删除:此 API 元素可能会在未来版本中删除。
      Finalization 已被弃用以移除。有关迁移选项的背景信息和详细信息,请参阅 Object.finalize()

      在已禁用或删除终结的 JVM 中运行时,没有对象将等待终结,因此此方法不执行任何操作。

      运行任何待完成的对象的完成方法。调用此方法表明 Java 虚拟机努力运行已被发现被丢弃但其 finalize 方法尚未运行的对象的 finalize 方法。当控制从方法调用返回时,虚拟机已尽最大努力完成所有未完成的终结。

      如果未显式调用 runFinalization 方法,虚拟机会根据需要在单独的线程中自动执行完成过程。

      System.runFinalization() 方法是调用此方法的常规且方便的方法。

      Java 语言规范:
      12.6 类实例的终结
      参见:
    • load

      public void load(String  filename)
      加载由文件名参数指定的本机库。文件名参数必须是绝对路径名。 (例如 Runtime.getRuntime().load("/home/avh/lib/libX11.so"); )。如果文件名参数在去除任何特定于平台的库前缀、路径和文件扩展名时指示名称为 L 的库,并且名为 L 的本机库与 VM 静态链接,则 JNI_OnLoad_L 函数调用库导出的,而不是尝试加载动态库。文件系统中不必存在与参数匹配的文件名。有关详细信息,请参阅 JNI规范。否则,文件名参数将以依赖于实现的方式映射到本地库映像。

      首先,如果有一个安全管理器,它的 checkLink 方法将以 filename 作为参数调用。这可能会导致安全异常。

      这类似于方法 loadLibrary(String) ,但它接受通用文件名作为参数而不仅仅是库名,从而允许加载任何本机代码文件。

      System.load(String) 方法是调用此方法的常规且方便的方法。

      参数:
      filename - 要加载的文件。
      抛出:
      SecurityException - 如果安全管理器存在且其 checkLink 方法不允许加载指定的动态库
      UnsatisfiedLinkError - 如果文件名不是绝对路径名,则本机库未与 VM 静态链接,或者库无法通过主机系统映射到本机库映像。
      NullPointerException - 如果 filenamenull
      参见:
    • loadLibrary

      public void loadLibrary(String  libname)
      加载由 libname 参数指定的本机库。 libname 参数不得包含任何特定于平台的前缀、文件扩展名或路径。如果名为 libname 的本机库与 VM 静态链接,则调用该库导出的 JNI_OnLoad_libname 函数。有关详细信息,请参阅 JNI规范。否则,libname 参数将从系统库位置加载,并以依赖于实现的方式映射到本机库映像。

      首先,如果有一个安全管理器,它的 checkLink 方法将以 libname 作为参数调用。这可能会导致安全异常。

      System.loadLibrary(String) 方法是调用此方法的常规且方便的方法。如果要在类的实现中使用本机方法,标准策略是将本机代码放在库文件中(称为 LibFile ),然后放置静态初始化程序:

       static { System.loadLibrary("LibFile"); }
       
      在类声明中。当类被加载和初始化时,本地方法所需的本地代码实现也将被加载。

      如果使用相同的库名称多次调用此方法,则忽略第二次和后续调用。

      参数:
      libname - 库的名称。
      抛出:
      SecurityException - 如果安全管理器存在且其 checkLink 方法不允许加载指定的动态库
      UnsatisfiedLinkError - 如果 libname 参数包含文件路径,则本机库未与 VM 静态链接,或者该库无法通过主机系统映射到本机库映像。
      NullPointerException - 如果 libnamenull
      参见:
    • version

      public static Runtime.Version  version()
      将 Java 运行时环境的版本返回为 Runtime.Version
      返回:
      Java运行时环境的Runtime.Version
      自从:
      9