1. 程式人生 > >聊聊Java中的Runtime類

聊聊Java中的Runtime類

概述

Runtime類封裝了執行時的環境。每個 Java 應用程式都有一個 Runtime 類例項,使應用程式能夠與其執行的環境相連線。

我們不能例項化一個Runtime物件,應用程式也不能建立自己的 Runtime 類例項,但可以通過 getRuntime 方法獲取當前Runtime執行時物件的引用。一旦得到了一個當前的Runtime物件的引用,就可以呼叫Runtime物件的方法去控制Java虛擬機器的狀態和行為

當Applet和其他不被信任的程式碼呼叫任何Runtime方法時,常常會引起SecurityException異常。

API方法示例

我們先來看看幾個native方法:

public native int availableProcessors();
public native long freeMemory();
public native long totalMemory();
public native long maxMemory();

使用示例如下:

Runtime rt = Runtime.getRuntime();
System.out.println("處理器數量:" + rt.availableProcessors()); //處理器數量:4
System.out.println("空閒記憶體數:" + rt.freeMemory() / 1024 / 1024 + "mb"); //空閒記憶體數:111mb
System.out.println("總記憶體數:" + rt.totalMemory() / 1024 / 1024 + "mb"); //總記憶體數:120mb
System.out.println("可用最大記憶體數:" + rt.maxMemory() / 1024 / 1024 + "mb"); //可用最大記憶體數:1910mb

使用場景: 通過totalMemory()和freeMemory()方法可以知道物件的堆記憶體有多大,還剩多少。

Java會週期性的回收垃圾物件(未使用的物件),以便釋放記憶體空間。但是如果想先於收集器的下一次指定週期來收集廢棄的物件,可以通過呼叫gc()方法來根據需要執行無用單元收集器。一個很好的試驗方法是先呼叫gc()方法,然後呼叫freeMemory()方法來檢視基本的記憶體使用情況,接著執行程式碼,然後再次呼叫freeMemory()方法看看分配了多少記憶體。

  • version()方法 (since Java9) java9t提供了Version方法,可以放我們和方便的獲取到執行時的一些引數資訊,可以說是非常的人性化。我們看看這個方法原始碼:
public static Version version() {
        if (version == null) {
            version = new Version(VersionProps.versionNumbers(),
                    VersionProps.pre(), VersionProps.build(),
                    VersionProps.optional());
        }
        return version;
}

我們發現所有的引數都來自於VersionProps,所以我們貼一些它的原始碼,大家就都清晰了

class VersionProps {
        private static final String launcher_name = "java";
        private static final String java_version = "10.0.2";
        private static final String java_version_date = "2018-07-17";
        private static final String java_runtime_name = "Java(TM) SE Runtime Environment";
        private static final String java_runtime_version = "10.0.2+13";
        private static final String VERSION_NUMBER = "10.0.2";
        private static final String VERSION_BUILD = "13";
        private static final String VERSION_PRE = "";
        private static final String VERSION_OPT = "";
        private static final boolean isLTS = "".startsWith("LTS");
        private static final String VENDOR_VERSION_STRING = "18.3";
        private static final String vendor_version = (VENDOR_VERSION_STRING.length() > 0
                        ? " " + VENDOR_VERSION_STRING : "");
        static {
            init();
        }
}

由於我的JDK版本是Java10,所以各位的引數可能和我的不太一樣。我執行一下如下:

System.out.println(Runtime.version()); //10.0.2+13

執行其它程式

在安全的環境中,可以在多工作業系統中使用Java去執行其他特別大的程序(也就是程式)。ecec()方法有幾種形式命名想要執行的程式和它的輸入引數。ecec()方法返回一個Process物件,可以使用這個物件控制Java程式與新執行的程序進行互動。ecec()方法本質是依賴於環境。

 public static void main(String[] args) throws IOException {
        Runtime rt = Runtime.getRuntime();
        //rt.exec("notepad.exe"); //開啟記事本 備註:.exe可以省略 下同
        Process process = rt.exec("calc.exe");//開啟計算器
        System.out.println(process); //Process[pid=8108, exitValue="not exited"]
 }

在新程式開始執行後就可以使用Process的方法了。可以用destory()方法殺死子程序,也可以使用waitFor()方法等待程式直到子程式結束,exitValue()方法返回子程序結束時返回的值。如果沒有錯誤,將返回0,否則返回非0。

public static void main(String[] args) throws IOException, InterruptedException {
        Runtime rt = Runtime.getRuntime();
        Process process = rt.exec("notepad.exe"); //開啟記事本 備註:.exe可以省略 下同
        //Process process = rt.exec("calc.exe");//開啟計算器
        process.waitFor(); //阻塞  等到子程序執行結束
        System.out.println("字進行執行完事了~~~");
        process.destroyForcibly(); //強制殺死子程序 destroy
 }

執行結果:(當關閉記事本後,會接著執行程式,列印資訊)

和Gc相關的方法

  • exit(int status)
    • 通過啟動虛擬機器的關閉序列,終止當前正在執行的 Java 虛擬機器。
  • gc()
    • 執行垃圾回收器。
  • halt(int status)
    • 強行終止目前正在執行的 Java 虛擬機器。

load和loadLibrary

這兩個方法是我們在使用Java的JNI機制時,會用到的一個非常重要的函式,它的作用即是把實現了我們在Java code中宣告的native方法的那個libraryload進來,或者load其他什麼動態連線庫

這兒JNI程式設計才會用到。小弟不才,這裡只能先給一個大寫的略字了