世界上并沒有完美的程序,但我們并不因此而沮喪,因為寫程序本來就是一個不斷追求完美的過程。 —— 書中引言
I、Java技術體系
Sun定義的Java技術體系包括:
- Java程序設計語言
- Java虛擬機
- Class文件格式
- Java API類庫
- 第三方Java類庫
Java程序設計語言、Java虛擬機、Java API類庫統(tǒng)稱為JDK(Java Development Kit),JDK是支持Java程序開發(fā)的最小環(huán)境。
Java API類庫中的Java SE API子集和Java虛擬機統(tǒng)稱為JRE(Java Runtime Environment),JRE是支持Java程序運行的最小標準環(huán)境。
II、Java內存區(qū)域
Java虛擬機所管理的內存會包括一下幾個運行時數(shù)據(jù)區(qū)域,如圖

1.程序計數(shù)器
- 簡介: 是一塊較小的內存空間,可以坐看是當前線程所執(zhí)行的字節(jié)碼的行號指示器。通俗點就是執(zhí)行第幾行代碼。分支、循環(huán)、跳轉、線程恢復等基礎功能都需要依賴計數(shù)器完成。
-
特點:
- 線程私有: 因為每條線程都需要有一個獨立的程序計數(shù)器,不然會混亂。
- 唯一一個沒有規(guī)定任何OOM情況的區(qū)域
- 如果線程正在執(zhí)行的是一個Java方法,則計數(shù)器記錄的是正在執(zhí)行的虛擬機字節(jié)碼指令的地址;如果執(zhí)行的是Native方法,計數(shù)器值為空。
2、Java虛擬機棧
- 簡介: Java虛擬機棧描述Java方法執(zhí)行的內存模型:每個方法在執(zhí)行時會創(chuàng)建一個棧幀,用于存儲局部變量表、操作數(shù)棧、動態(tài)鏈接、方法出口等信息,每一個方法從調用到執(zhí)行完成,就對應著一個棧幀在虛擬機棧中的入棧出棧過程。
-
特點
- 線程私有,生命周期與線程相同
- 此區(qū)域規(guī)定了兩種異常情況:
- 線程請求的棧深度大于虛擬機所允許的深度, 拋出StackOverflowError
- 無法獲取足夠的內存,拋出OutOfMemoryError
- 局部變量表存放了編譯器可知的各種基本數(shù)據(jù)類型、對象引用、returnAddress類型。其中64位的long/double類型的數(shù)據(jù)會占用2個局部變量空間(Slot),其余數(shù)據(jù)類型占用一個。局部變量表所需的內存空間在編譯期間完成分配,方法運行期間不會改變局部變量表的大小。
3.本地方法棧
- 簡介: 本地方法棧與虛擬機棧所發(fā)揮的作用是非常相似的,區(qū)別是虛擬機棧為虛擬機執(zhí)行Java方法服務,而本地方法棧為虛擬機使用到的Native方法服務。
-
特點
- 線程私有,生命周期與線程相同
- 此區(qū)域規(guī)定了兩種異常情況:
- 線程請求的棧深度大于虛擬機所允許的深度, 拋出StackOverflowError
- 無法獲取足夠的內存,拋出OutOfMemoryError
4.Java堆
- 簡介: 對大多數(shù)應用來說,Java堆是Java虛擬機所管理的內存中最大的一塊,在虛擬機啟動時創(chuàng)建。此內存區(qū)域唯一目的就是存放對象實例,幾乎所有的對象實例都在這里分配內存。
-
特點
- Java堆是垃圾收集器管理的主要區(qū)域,因此又被稱為“GC堆”
- 所有線程共享
- Java堆可以處于物理上不連續(xù)的內存空間中,只要邏輯上是連續(xù)的就可以。
- 如果堆無法再擴展時,會拋出OutOfMemoryError
5.方法區(qū)
- 簡介: 方法區(qū)用于存儲已被虛擬機加載的類信息、常量、靜態(tài)常量、即時編譯器編譯后的代碼等數(shù)據(jù)。
-
特點
- 所有線程共享
- 如果無法滿足內存分配時,會拋出OutOfMemoryError
6.運行時常量池
- 簡介: 運行時常量池是方法區(qū)的一部分。Class文件中除了有類的版本、字段、方法、接口等描述信息外,還有一項信息是常量池,用于存放編譯期生成的各種字面量和符號引用,這部分內容在類加載后進入方法區(qū)的運行時常量池中存放。
-
特點
- 具有動態(tài)性,運行期間也可將常量放入池中,利用較多的就是String的intern()方法。
- 如果無法滿足內存分配時,會拋出OutOfMemoryError
7.直接內存
- 簡介:直接內存是物理機的內存。由于JDK1.4引入了NIO類,可以使用Native函數(shù)庫直接分配堆外內存。
-
特點
- 會拋出OutOfMemoryError0