Java虛擬機內存存儲結構以及GC回收算法的淺析

JVM內存結構:

堆:存放所有new出來的東西。GC堆是Java虛擬機所管理的內存中最大的一塊內存區域,也是被各個線程共享的內存區域。堆被分爲新生代和老年代。

方法區:存儲虛擬機加載的類信息,常量,靜態變量,各個內存共享的內存區域。默認大小爲16mb,最大值爲64mb

虛擬機棧:描述的是Java方法執行的內存模型。每一個方法被執行的時候,都會創建一個“棧幀”,用於存儲局部變量表,操作棧,方法出口等。

本地方法棧:爲Native方法服務。

程序計數器:分支、循環、跳轉、異常處理、線程恢復。

JVM啓動流程:

JVM基本結構:


GC回收機制:

判斷對象是否存活:

1.引用計數:每個對象都有一個引用計數屬性,新增一個引用時計數加1,引用釋放時減1,計數爲0的時候可回收。

2.可達性分析:從GC Roots開始向下搜索,搜索所走過的路徑稱爲引用鏈,當一個對象沒有任何引用鏈相連時,則該對象不可用,回收。

GC回收的四個算法:

1.標記-清除算法:該算法分爲兩個階段:

1>標記階段:找到所有可訪問的對象,做個標記

 2>清除階段:遍歷堆,找到未被標記的對象回收

優點:

1>可以解決循環引用的問題

2>必要時纔回收

缺點:

1>回收時,應用需要掛起,也就是stop the world.

2>標記和清除的效率不高,尤其是掃描的對象比較多的時候

2.複製算法:

首先將內存分爲大小相等的兩部分(假設A、B兩部分),每次呢只使用其中的一部分(這裏我們假設爲A區),等這部分用完了,這時候就將這裏面還能活下來的對象複製到另一部分內存(這裏設爲B區)中,然後把A區中的剩下部分全部清理掉。

優點:

  1. 吞吐量大,只需要遍歷一次From空間Sweep需要遍歷兩次,而且只複製存活的對象。
  2. 高速分配,不需要通過空閒鏈表直接在連續的內存上進行分配。
  3. 沒有碎片。
  4. 與緩存兼容,複製存活對象時採用深度優先算法使相關聯的對象都在附近。

缺點:

  1. 堆的使用效率低,必須分配一個To,其不能分配對象。
  2. 不兼容保守式GC算法,需要移動對象。
  3. 遞歸調用,複製對象的深度優先算法是通過遞歸調用實現的,遞歸將消耗棧等資源。

3.標記-整理算法:算法不直接對可回收對象進行清理,而是讓所有可用的對象都向一端移動。然後直接清理掉邊界意外的內存。

4.分帶收集算法:

根據對象的存活週期不同將內存劃分爲新生代和老年代,存活週期短的爲新生代,存活週期長的爲老年代。這樣就可以根據每塊內存的特點採用最適當的收集算法。 

新生代的中每次垃圾收集中會發現有大批對象死區,只有少量存活,那就選用複製算法,只需要付出少量存活對象的複製成本就可以完成收集。 
老年代中因爲對象的存活率高,沒有額外的控件對它進行分配擔保,就必須使用“標記-清掃”或者“標記-整理”算法來進行回收。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章