1. 程式人生 > 實用技巧 >JVM記憶體結構分析

JVM記憶體結構分析

2019獨角獸企業重金招聘Python工程師標準>>> hot3.png

最近由於工作需要參考了一些文章和書籍研究一下JVM原理和優化,接下來會簡單總結一下,希望能夠幫助到有需要的人。

  • 記憶體結構

1、堆(Heap)記憶體

1)執行時資料區域,所有類例項和陣列的記憶體均從此處分配。Java虛擬機器啟動時建立。

2)組成

組成

詳解

Young Generation

即圖中的Eden + From Space + To Space
Eden存放新生的物件
Survivor Space有兩個,存放每次垃圾回收後存活的物件

Old Generation

Tenured Generation即圖中的Old Space

主要存放應用程式中生命週期長的存活物件

2、非堆記憶體

1)JVM具有一個由所有執行緒共享的方法區。方法區屬於非堆記憶體。它儲存每個類結構,如執行時常數池、欄位和方法資料,以及方法的程式碼。它是在Java虛擬機器啟動時建立的。

2)除了方法區外,Java虛擬機器還需要用於內部處理或優化的記憶體,這種記憶體也是非堆記憶體。例如,JIT編譯器需要記憶體來儲存從Java虛擬機器程式碼轉換而來的本機程式碼,從而獲得高效能。

組成

詳解

Permanent Generation

即圖中的Permanent Space
存放JVM自己的反射物件,比如類物件和方法物件、jar包相關meta資訊

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