1. 程式人生 > >java虛擬機器(第二版) 第二章總結 (一)

java虛擬機器(第二版) 第二章總結 (一)

本文主要是up主閱讀java虛擬機器(第二版) 第二章總結的總結,因為第一章主要講了java體系的過去和展望,故就暫時總結了,感興趣的可以閱讀原書。

另外推薦看原書,原書對我總結的知識有更細緻的解讀。

眾所周知,java虛擬機器對記憶體的自動管理,讓java程式設計師少了好多手動管理記憶體的操作,省了不少事情,但也讓記憶體洩漏和記憶體溢位等記憶體問題變的“高深莫測”。畢竟不常用到的東西就會越不熟悉。

1、(原書2.2.1)程式計數器

執行緒私有,可以看成是當前執行緒所執行的位元組碼的行號指示器,在虛擬機器的概念模型彙總,比如分支、迴圈、跳轉、執行緒恢復等都依賴於這個計數器的值,特別是在多執行緒環境,每個執行緒是來回切換的,正是程式計數器保證切換後能恢復到正確的執行位置。是唯一一個不會丟擲OutOfMemoryError異常的區域。

 

2、(原書2.2.2)java虛擬機器棧

執行緒私有,我們常把java記憶體籠統的劃分為堆記憶體和棧記憶體,而棧記憶體其實就是指的虛擬機器棧,或者說是虛擬機器棧中的區域性變量表部分。虛擬機器棧是方法執行的記憶體模型,每個方法執行時都會建立一個棧幀。方法從呼叫到執行完成的過程, 就對應著一個棧幀在虛擬機器棧中入棧到出棧的過程。棧幀可以閱讀書中第八章內容或者等up主進行總結。

區域性變量表可存放各種基本資料型別( boolean、 byte、 char、 short、 int、float、 long、 double) 、 物件引用和returnAddress型別 。

 

會出現兩種異常:StackOverflowError和OutOfMemoryError,前者是由於執行緒請求棧深度大於虛擬機器的可用棧深度丟擲,後者虛擬機器棧無法擴充套件到足夠的記憶體時丟擲,(當-Xmx和-Xms引數相同時,棧記憶體為固定大小,不可擴充套件,當兩個引數不同時,棧可擴充套件)

 

3、(原書2.2.3)本地方法棧

執行緒私有,和虛擬棧作用非常相似,唯一不同是此區域是為虛擬機器使用到的Native方法服務。同樣會丟擲StackOverflowError和OutOfMemoryError兩個異常。

 

4、(原書2.2.4)java堆

執行緒共享,幾乎所有例項物件都在此區域存放,(JIT編譯器的發展與逃逸分析技術逐漸成熟, 棧上分配、 標量替換等的應用使得所有物件都在堆上分配變的不是那麼”絕對”,上面幾個名詞書中有詳細介紹)。

是垃圾收集器管理的主要區域。被分為Eden空間、 From Survivor空間、 To Survivor空間等(如果使用java自帶的VisualVM檢視,可以看到此類劃分中各個空間實時的使用情況)。

此區域會丟擲OutOfMemoryError異常。

 

5、(原書2.2.5)方法區(現在叫元資料區)

執行緒共享,用於儲存已被虛擬機器載入的類資訊、 常量、 靜態變數、 即時編譯器編譯後的程式碼等資料。

會丟擲OutOfMemoryError異常


6、(原書2.2.6)執行時常量池

執行緒共享,為方法區的一部分,用於存放編譯期生成的各種字面量和符號引用。

 

7、(原書2.2.7)直接記憶體

即為你機器的真是記憶體大小,和java虛擬機器無關的記憶體區域,但頻繁地被使用, 而且也可能導致OutOfMemoryError異常出現。

特別是jdk1.4後加入的NIO類,它可以使用Native函式庫直接分配堆外記憶體,因避免了在Java堆和Native堆中來回複製資料
而顯著提高效能,但如果堆記憶體太大導致直接記憶體不夠使用,也會丟擲OutOfMemoryError。(有時我們機器會報OutOfMemoryError,但在我們調大堆記憶體或者方法區的記憶體或者棧記憶體等操作後還是會報OutOfMemoryError,此時就要考慮系是不是直接記憶體不夠用了)。

 

本文暫時總結了java虛擬機器(第二版)中的2.2節的主要知識點,和一些up主自己的知識點,如果有記憶差錯,還望見諒,後面我會找時間繼續的,最後,我總結的知識點比較簡練,如果需要了解詳細內容的話,請閱讀原書。也歡迎大家關注我的公眾號號 “up隨想”,關注後或許會收到up主的小福利哦!!