package java.lang; import sun.reflect.CallerSensitive; import sun.reflect.Reflection; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.StringTokenizer; /** * Runtime类,里面能够得到应用运行时的一些状态(主要包括使用的内存和cpu个数)和在应用运行时执行一些操做(程序退出、执行gc、设置退出时的钩子函数)。 * 用到了单例模式:确保一个类最多只有一个实例,并提供一个全局访问点。 */ public class Runtime { private static Runtime currentRuntime = new Runtime(); /** * 应用了设计模式中的单例模式饿汉式(线程安全) * 返回与当前应用程序相关的java运行时对象。 */ public static Runtime getRuntime() { return currentRuntime; } /** * 私有构造函数,单例模式的条件,返回与当前应用程序相关的java运行时对象,不支持new的Runtime */ private Runtime() { } /** * 经过启动虚拟机的关闭序列,终止当前正在运行的 Java 虚拟机。此方法从不正常返回。能够将变量做为一个状态码;根据惯例,非零的状态码表示非正常终止。 * 虚拟机的关闭序列包含两个阶段。在第一个阶段中,会以某种未指定的顺序启动全部已注册的关闭钩子(hook)(若是有的话),而且容许它们同时运行直至结束。 * 在第二个阶段中,若是已启用退出终结,则运行全部未调用的终结方法。一旦完成这个阶段,虚拟机就会暂停。 * 若是在虚拟机已开始其关闭序列后才调用此方法,那么若正在运行关闭钩子,则将无限期地阻断此方法。 * 若是已经运行完关闭钩子,而且已启用退出终结 (on-exitfinalization),那么此方法将利用给定的状态码(若是状态码是非零值)暂停虚拟机;不然将无限期地阻断虚拟机。 */ public void exit(int status) { SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkExit(status); } Shutdown.exit(status); } /** * 注册新的虚拟机来关闭钩子。 */ public void addShutdownHook(Thread hook) { SecurityManager sm = System.getSecurityManager(); if (sm != null) { sm.checkPermission(new RuntimePermission("shutdownHooks")); } ApplicationShutdownHooks.add(hook); } /** * 取消注册某个先前已注册的虚拟机关闭钩子。 * 若是指定的钩子先前已注册而且成功地取消注册,则返回 true,其余状况返回 false。 */ public boolean removeShutdownHook(Thread hook) { SecurityManager sm = System.getSecurityManager(); if (sm != null) { sm.checkPermission(new RuntimePermission("shutdownHooks")); } return ApplicationShutdownHooks.remove(hook); } /** * 强行终止目前正在运行的 Java 虚拟机。此方法从不正常返回。 * 应当心使用此方法。与 exit方法不一样,此方法不会启动关闭钩子,而且若是已启用退出终结,此方法也不会运行未调用的终结方法。 * 若是已经发起关闭序列,那么此方法不会等待全部正在运行的关闭钩子或终结方法完成其工做。 */ public void halt(int status) { SecurityManager sm = System.getSecurityManager(); if (sm != null) { sm.checkExit(status); } Shutdown.halt(status); } /** * 在退出时启用或禁用终结;这样作可指定拥有未被自动调用终结方法的全部对象的终结方法,并将在退出 Java 运行时前运行此终结方法。默认状况下,禁用退出终结。 * 若是有安全管理器,则首先使用 0 做为变量来调用其 checkExit 方法,以确保容许退出。这可能会致使 SecurityException。 */ @Deprecated public static void runFinalizersOnExit(boolean value) { SecurityManager security = System.getSecurityManager(); if (security != null) { try { security.checkExit(0); } catch (SecurityException e) { throw new SecurityException("runFinalizersOnExit"); } } Shutdown.setRunFinalizersOnExit(value); } /** * 在单独的进程中执行指定的字符串命令。 * 对于 exec(command) 形式的调用而言,其行为与调用 exec(command, null, null) 彻底相同。 */ public Process exec(String command) throws IOException { return exec(command, null, null); } /** * 在指定环境的单独进程中执行指定的字符串命令。 * 对于 exec(command, envp) 形式的调用而言,其行为与调用 exec(command, envp, null) 彻底相同。 */ public Process exec(String command, String[] envp) throws IOException { return exec(command, envp, null); } /** * 在有指定环境和工做目录的独立进程中执行指定的字符串命令。 * 对于 exec(command, envp, dir) 形式的调用而言,其行为与调用 exec(cmdarray, envp, dir) 彻底相同,其中 cmdarray 是 command 中全部标记的数组。 * 更准确地说,可使用经过调用 new StringTokenizer(command) 建立的 StringTokenizer 将 command 字符串拆解成标记,调用时不对字符类别作进一步的修改。 * 而后将标记生成器所生成的标记以相同的顺序放入新的字符串数组 cmdarray 中。 */ public Process exec(String command, String[] envp, File dir) throws IOException { if (command.length() == 0) throw new IllegalArgumentException("Empty command"); StringTokenizer st = new StringTokenizer(command); String[] cmdarray = new String[st.countTokens()]; for (int i = 0; st.hasMoreTokens(); i++) cmdarray[i] = st.nextToken(); return exec(cmdarray, envp, dir); } /** * 在单独的进程中执行指定命令和变量。 * 对于 exec(cmdarray) 形式的调用而言,其行为与调用 exec(cmdarray, null, null) 彻底相同。 */ public Process exec(String cmdarray[]) throws IOException { return exec(cmdarray, null, null); } /** * 在指定环境的独立进程中执行指定命令和变量。 * 对于 exec(cmdarray, envp) 形式的调用而言,其行为与调用 exec(cmdarray, envp, null) 彻底相同。 */ public Process exec(String[] cmdarray, String[] envp) throws IOException { return exec(cmdarray, envp, null); } /** * 在指定环境和工做目录的独立进程中执行指定的命令和变量。 * 给定的字符串数组 cmdarray 表示一个命令行标记,字符串数组 envp 则表示“环境”变量设置,此方法会建立一个新进程,而指定的命令就在这个进程中执行。 * 此方法检查 cmdarray 是不是一条有效的操做系统命令。哪些命令有效取决于系统,可是该命令至少必须有一个非 null 字符串的非空列表。 */ public Process exec(String[] cmdarray, String[] envp, File dir) throws IOException { return new ProcessBuilder(cmdarray) .environment(envp) .directory(dir) .start(); } /** * 向 Java 虚拟机返回可用处理器的数目。 * 该值在特定的虚拟机调用期间可能发生更改。所以,对可用处理器数目很敏感的应用程序应该不按期地轮询该属性,并相应地调整其资源用法。 * 虚拟机可用的最大处理器数目;从不小于 1 */ public native int availableProcessors(); /** * 返回 Java 虚拟机中的空闲内存量。调用 gc 方法可能致使 freeMemory 返回值的增长。 */ public native long freeMemory(); /** * 返回 Java 虚拟机中的内存总量。此方法返回的值可能随时间的推移而变化,这取决于主机环境。 */ public native long totalMemory(); /** * 返回 Java 虚拟机试图使用的最大内存量。若是内存自己没有限制,则返回值 Long.MAX_VALUE。 */ public native long maxMemory(); /** * 运行垃圾回收器。调用此方法意味着 Java 虚拟机作了一些努力来回收未用对象,以便可以快速地重用这些对象当前占用的内存。 * 当控制从方法调用中返回时,虚拟机已经尽最大努力回收了全部丢弃的对象。 * 垃圾回收机制主要有两类:引用计数收集器 跟踪收集器 */ public native void gc(); /* Wormhole for calling java.lang.ref.Finalizer.runFinalization */ private static native void runFinalization0(); /** * 运行挂起 finalization 的全部对象的终止方法。 * 调用此方法意味着 Java 虚拟机作了一些努力运行已被丢弃对象的 finalize 方法, * 可是这些对象的 finalize 方法尚未运行。当控制从方法调用中返回时,Java 虚拟机已经尽最大努力去完成全部未执行的终止方法。 * 若是不显式调用 runFinalization 方法,则 Java 虚拟机会根据须要在单独的线程中自动执行此终止过程。 */ public void runFinalization() { runFinalization0(); } /** * 启用/禁用指令跟踪。 */ public native void traceInstructions(boolean on); /** * 启用/禁用方法调用跟踪。 */ public native void traceMethodCalls(boolean on); /** * 加载具备指定动态库。 */ @CallerSensitive public void load(String filename) { load0(Reflection.getCallerClass(), filename); } synchronized void load0(Class<?> fromClass, String filename) { SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkLink(filename); } if (!(new File(filename).isAbsolute())) { throw new UnsatisfiedLinkError( "Expecting an absolute path of the library: " + filename); } ClassLoader.loadLibrary(fromClass, filename, true); } /** * 加载具备指定动态库。 */ @CallerSensitive public void loadLibrary(String libname) { loadLibrary0(Reflection.getCallerClass(), libname); } synchronized void loadLibrary0(Class<?> fromClass, String libname) { SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkLink(libname); } if (libname.indexOf((int) File.separatorChar) != -1) { throw new UnsatisfiedLinkError( "Directory separator should not appear in library name: " + libname); } ClassLoader.loadLibrary(fromClass, libname, false); } /** * 建立输入流的本地化版本。此方法获取 InputStream,并返回除本地化外其余全部方面都和变量等效的 InputStream,这些方面包括:做为本地字符集中的字符从流中被读取,并将它们从本地字符集自动转换为 Unicode。 */ @Deprecated public InputStream getLocalizedInputStream(InputStream in) { return in; } /** * 建立输出流的本地化版本。此方法获取 OutputStream,并返回除本地化外其余全部方面都和变量等效的 OutputStream,这些方面包括:做为 Unicode 字符被写入流中,并被自动转换为本地字符集。 * 若是参数已是本地流,则可做为结果返回。 */ @Deprecated public OutputStream getLocalizedOutputStream(OutputStream out) { return out; } }