JVM記憶體結構分析
最近由於工作需要參考了一些文章和書籍研究一下JVM原理和優化,接下來會簡單總結一下,希望能夠幫助到有需要的人。
記憶體結構
1、堆(Heap)記憶體
1)執行時資料區域,所有類例項和陣列的記憶體均從此處分配。Java虛擬機器啟動時建立。
2)組成
組成 |
詳解 |
Young Generation |
即圖中的Eden + From Space + To Space |
Old Generation |
Tenured Generation即圖中的Old Space |
2、非堆記憶體
1)JVM具有一個由所有執行緒共享的方法區。方法區屬於非堆記憶體。它儲存每個類結構,如執行時常數池、欄位和方法資料,以及方法的程式碼。它是在Java虛擬機器啟動時建立的。
2)除了方法區外,Java虛擬機器還需要用於內部處理或優化的記憶體,這種記憶體也是非堆記憶體。例如,JIT編譯器需要記憶體來儲存從Java虛擬機器程式碼轉換而來的本機程式碼,從而獲得高效能。
組成 |
詳解 |
Permanent Generation |
即圖中的Permanent Space |
native heap |
JVM內部處理或優化 |
記憶體管理
1、分代GC策略
組成 |
詳解 |
堆(Heap)記憶體 |
JVM採用一種分代回收(generational collection)的策略,用較高的頻率對年輕的物件(young generation)進行掃描和回收,這種叫做minor collection,而對老物件(old generation)的檢查回收頻率要低很多,稱為major collection。這樣就不需要每次GC都將記憶體中所有物件都檢查一遍,以便讓出更多的系統資源供應用系統使用。 |
非堆記憶體 |
GC不會在主程式執行期對PermGen Space進行清理,所以如果你的應用中有很多CLASS的話,就很可能出現PermGen Space錯誤。 |
2、記憶體分配(申請)過程
步驟 |
操作 |
1 |
JVM會試圖為相關Java物件在Eden中初始化一塊記憶體區域; |
2 |
當Eden空間足夠時,記憶體申請結束。否則到下一步; |
3 |
JVM試圖釋放對Eden中所有不活躍的物件minor collection,釋放後若Eden空間仍然不足以放入新物件,則試圖將部分Eden中活躍物件放入Survivor區; |
4 |
Survivor區被用來作為Eden及OLD的中間交換區域,當OLD區空間足夠時,Survivor區的物件會被移到Old區,否則會被保留在Survivor區; |
5 |
當OLD區空間不夠時,JVM會在OLD區進行major collection; |
6 |
完全垃圾收集後,若Survivor及OLD區仍然無法存放從Eden複製過來的部分物件,導致JVM無法在Eden區為新物件建立記憶體區域,則出現"Out of memory錯誤" |
3、物件衰老過程
步驟 |
操作 |
1 |
young generation的記憶體,由一塊Eden和兩塊Survivor Space構成。新建立物件的記憶體都分配自eden。兩塊Survivor Space總有會一塊是空閒的,用作copying collection的目標空間。Minor collection的過程就是將eden和在用survivor space中的活物件copy到空閒survivor space中。物件在young generation裡經歷了一定次數的minor collection後,年紀大了,就會被移到old generation中,稱為tenuring。 |
2 |
剩餘記憶體空間不足會觸發GC,如eden空間不夠了就要進行minor collection,old generation空間不夠要進行major collection,permanent generation空間不足會引發Full GC。 |
轉載於:https://my.oschina.net/Sheamus/blog/371132