複製鏈接
請複製以下鏈接發送給好友

runtime

(內存管理)

鎖定
運行時刻是指一個程序在運行(cc或者在被執行)的狀態。也就是説,當你打開一個程序使它在電腦上運行的時候,那個程序就是處於運行時刻。在一些編程語言中,把某些可以重用的程序或者實例打包或者重建成為“運行庫”。這些實例可以在它們運行的時候被鏈接或者被任何程序調用。 [1] 
中文名
運行時刻
外文名
runtime
常見應用
內存管理
含    義
程序在運行的狀態

runtime簡介

開發者有時候會在什麼東西應該在編譯的時候加載進來以及什麼東西該在運行的時候使用之間做出抉擇,前者有時候被稱為編譯時期。
一段時間以來,技術類作者都拒絕使用"運行時刻"作為一種術語,他們堅持類似於"一個程序在運行"之類的説法,用以避免需要一個專門的術語。後來,這個術語逐漸地蔓延到通常的應用中。

runtime相關內容

Runtime類封裝了運行時的環境。每個Java應用程序都有一個Runtime 類實例,使應用程序能夠與其運行的環境相連接。
一般不能實例化一個Runtime對象,應用程序也不能創建自己的Runtime 類實例,但可以通過getRuntime 方法獲取當前Runtime運行時對象的引用。
一旦得到了一個當前的Runtime對象的引用,就可以調用Runtime對象的方法去控制Java虛擬機的狀態和行為。
Applet和其他不被信任的代碼調用任何Runtime方法時,常常會引起SecurityException異常。

runtime常見應用

1、內存管理:
Java提供了無用單元自動收集機制。通過totalMemory()和freeMemory()方法可以知道對象的堆內存有多大,還剩多少。
Java會週期性的回收垃圾對象(未使用的對象),以便釋放內存空間。但是如果想先於收集器的下一次指定週期來收集廢棄的對象,可以通過調用gc()方法來根據需要運行無用單元收集器。一個很好的試驗方法是先調用gc()方法,然後調用freeMemory()方法來查看基本的內存使用情況,接着執行代碼,然後再次調用freeMemory()方法看看分配了多少內存。下面的程序演示了這個構想。
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 is : " + mem1);
r.gc();
mem1 = r.freeMemory();
System.out.println("Free memory after garbage collection : " + mem1);
//allocate integers
for(int i=0; i<1000; i++) someints[i] = new Integer(i);
mem2 = r.freeMemory();
System.out.println("Free memory after allocation : " + mem2);
System.out.println("Memory used by allocation : " +(mem1-mem2));
//discard Intergers
for(int i=0; i<1000; i++) someints = null;
r.gc(); //request garbage collection
mem2 = r.freeMemory();
System.out.println("Free memory after collecting " + "discarded integers : " + mem2);
}
}
編譯後運行結果如下(不同的機器不同時間運行的結果也不一定一樣):
Total memory is :2031616
Initial free is : 1818488
Free memory after garbage collection : 1888808
Free memory after allocation : 1872224
Memory used by allocation : 16584
Free memory after collecting discarded integers : 1888808
2、執行其他程序
在安全的環境中,可以在多任務操作系統中使用Java去執行其他特別大的進程(也就是程序)。exec()方法有幾種形式命名想要運行的程序和它的輸入參數。exec()方法返回一個Process對象,可以使用這個對象控制Java程序與新運行的進程進行交互。exec()方法本質是依賴於環境。
下面的例子是使用exec()方法啓動windows的記事本notepad。這個例子必須在Windows操作系統上運行。
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.");
}
}
}
exec()還有其他幾種形式,例子中演示的是最常用的一種。exec()方法返回Process對象後,在新程序開始運行後就可以使用Process的方法了。可以用destory()方法殺死子進程,也可以使用waitFor()方法等待程序直到子程序結束,exitValue()方法返回子進程結束時返回的值。如果沒有錯誤,將返回0,否則返回非0。下面是關於exec()方法的例子的改進版本。例子被修改為等待,直到運行的進程退出:
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());
}
}
下面是運行的結果(當關閉記事本後,會接着運行程序,打印信息):
Notepad returned 0
任意鍵繼續. . .
當子進程正在運行時,可以對標準輸入輸出進行讀寫。getOutputStream()方法和getInPutStream()方法返回對子進程的標準輸入和輸出。

runtime系統

Run-time system
一個run-time system也叫做運行時系統,運行時環境,實現了一個計算機語言的核心行為。
每一種計算機語言都實現了某種形式的運行時系統,無論這種語言是編譯語言解釋語言,還是嵌入式領域特定語言。【compiled language, interpreted language, embedded domain-specific language】或者有些語言會通過API調用以線程形式調用。除了要支持語言的低級行為之外,一個運行時系統還要實現更高層次的行為,甚至要執行類型檢查,調試,或者代碼生成與優化。
作為一個簡單的運行時系統的例子,C語言的運行時系統是編譯器插入到可執行文件中的一個特殊的指令集合。此外,這些特殊的指令集合還管理處理器棧,為局部變量分配空間,並把函數調用參數拷貝到棧頂。之所以這些行為是運行時系統的一部分而不是語言的關鍵部分,是因為這些行為時系統行為,這些行為在程序的執行全過程中維護了棧的狀態。並且這些系統行為實現了語言的執行模型,而不是實現了與特定計算結果有關的語義。
另一個展示運行時系統特性的例子是使用API與運行時系統交互。對這個API的調用看起來就像是對軟件庫的調用一樣,然而運行時系統添加了實現了一個執行模型的系統性行為。這裏的API添加了插樁代碼會調用運行時系統,而不是使用一個包含代碼的庫直接實現軟件行為。一個人只要瞭解構成一個庫的語言就能夠理解這個庫的行為。然而,一個人要想了解剛才那個調用運行時庫的API不能只瞭解構成API的語言本身。還要知道由運行時系統實現的執行模型是什麼樣的。
這就是一種嵌入式語言如posix threads和一個軟件庫的區別。雖然posix threads和軟件庫都是通過一個API調用,但是posix threads的行為不能通過代碼用的語言本身理解。實際上posix threads的調用還是要依賴於運行時系統提供的執行模型。
某些compiled或者interpreted的語言提供一個允許應用代碼直接和運行時系統交互的接口。一個例子是JAVA中的Thread類,通常情況下一個語言的核心行為(如任務調度和資源管理)是不能夠通過這種方式使得應用代碼能夠接觸到的。

runtime其他信息

API預覽
addShutdownHook(Thread hook)
註冊新的虛擬機來關閉掛鈎。
availableProcessors()
向 Java虛擬機返回可用處理器的數目。
exec(String command)
在單獨的進程中執行指定的字符串命令。
exec(String[] cmdarray)
在單獨的進程中執行指定命令和變量。
exec(String[] cmdarray, String[] envp)
在指定環境的獨立進程中執行指定命令和變量。
exec(String[] cmdarray, String[] envp, File dir)
在指定環境和工作目錄的獨立進程中執行指定的命令和變量。
exec(String command, String[] envp)
在指定環境的單獨進程中執行指定的字符串命令。
exec(String command, String[] envp, File dir)
在有指定環境和工作目錄的獨立進程中執行指定的字符串命令。
exit(int status)
通過啓動虛擬機的關閉序列,終止當前正在運行的 Java虛擬機。
freeMemory()
返回 Java虛擬機中的空閒內存量。
gc()
運行垃圾回收器。
InputStream getLocalizedInputStream(InputStream in)
已過時。 從 JDK 1.1 開始,將本地編碼字節流轉換為 Unicode字符流的首選方法是使用 InputStreamReader 和 BufferedReader 類。
OutputStream getLocalizedOutputStream(OutputStream out)
已過時。 從 JDK 1.1 開始,將 Unicode字符流轉換為本地編碼字節流的首選方法是使用 OutputStreamWriter、BufferedWriter 和 PrintWriter 類。
getRuntime()
返回與當前 Java應用程序相關的運行時對象。
halt(int status)
強行終止正在運行的 Java 虛擬機。
load(String filename)
加載作為動態庫的指定文件名。
loadLibrary(String libname)
加載具有指定庫名的動態庫。
maxMemory()
返回 Java虛擬機試圖使用的最大內存量。
removeShutdownHook(Thread hook)
取消註冊某個先前已註冊的虛擬機關閉掛鈎。
runFinalization()
運行掛起 finalization 的所有對象的終止方法。
runFinalizersOnExit(value)
已過時。 此方法本身具有不安全性。它可能對正在使用的對象調用終結方法,而其他線程正在操作這些對象,從而導致不正確的行為或死鎖。
totalMemory()
返回 Java虛擬機中的內存總量。
traceInstructions(on)
啓用/禁用指令跟蹤
traceMethodCalls(on)
啓用/禁用方法調用跟蹤。
參考資料
  • 1.    周繼松,陳偉主編.《Java面向對象程序設計》:重慶大學電子音像出版社,2020年:159頁