JVM內存結構和垃圾回收

JVM內存結構和垃圾回收

JVM運行時數據區

方法區:永久代 線程共享 用於存儲已被虛擬機加載的類信息、常量、靜態變量、JIT編譯後的代碼等數據。

堆(Heap):新生代,老年代 線程共享 所有的對象實例以及都要在堆上分配。

虛擬機棧:VM Stack 線程私有 Java方法執行的內存模型:方法執行時創建棧幀(Stack Frame)用戶存儲局部變量表、操作數棧、動態鏈接、方法入口等信息。每個方法從調用直至執行完成的過程就對應著一個棧幀在VMStack 中的入棧和出棧過程

本地方法棧:Native Method Stack 與VM Stack 類似,區別在於VM Stack為虛擬機執行Java方法(字節碼)服務,而Native Method Stack則是VM使用到的Native方法服務

程序計數器:Program CounterRegister 線程私有 可看作是當前線程所執行的字節碼行號指示器

所有的對象實例以及都要在堆上分配。

The heap is the runtime data area from which memory for all class instances and arrays is allocated.

垃圾回收

垃圾回收主要發生在堆中。

引用計數:難以解決對象之間的相互循環引用的問題,一般JVM不用,但是Pythoon中會用到

可達性分析算法

JVM一般使用可達性分析算法帶判斷垃圾

使用GC Roots作為起始點,向下搜索,當發現與GC Roots沒有關聯則判定為可以回收的對象

可作為GC Roots的對象

1. VM Stack(棧幀中的本地變量表)中引用的對象

2. 方法區中類靜態屬性引用的對象

3. 方法區中常量引用的對象

4. 本地方法棧中JNI引用的對象

垃圾收集算法

1.標記清除(Mark-Sweep):最基礎的算法,兩點不足:1.效率問題,標記和清除效率都不高 2.空間問題,會產生大量不連續的內存碎片

2.複製算法

把heap分為兩塊,有用的複製到另一個塊,清除原來的塊

現代商業JVM都採用這種算法來回收新生代:

將內存劃分為較大的Eden和Survivor,HotSpot默認是8:1

3.標記整理

4.分代收集

內存分配與回收策略

1. 對象優先在Eden分配

2. 大對象直接進入老年代(很長的字符串和數組,寫代碼應當避免短命大對象)

3. 長期存活的對象直接進入老年代

4. 動態對象年齡判斷(在Survivor空間中,如果相同年齡所以對象大小的總和大於Survivor空間的一半,年齡大於等於該年齡的對象直接進入老年代)

5. 空間分配擔保


分享到:


相關文章: