JVM中的內存劃分與垃圾回收算法

一、內存劃分
下面這張圖完美的展示了JVM的內存劃分

阿斯達
可以看出,JVM將內存劃分爲堆區和非堆區,非堆區用來存儲編譯和保存的本地代碼、虛擬機自己的靜態數據、方法參數、局域變量等的引用以及方法執行順序、本地方法的調用棧;而堆區則是存放創建的對象等。

下圖所示是堆中內存分配示意圖,創建一個對象,首先會在eden區域分配區域,如果內存不夠,就會將年齡大的轉移到Survivor區,當survivor區域存儲不下,則會轉移年老代的。對於一些靜態變量不需要使用對象,直接調用的,則會被放入永生代。一般來說長期存活的對象最終會被存放到年老代,還有一種特殊情況也會被存放到年老代,就是創建大對象時,比如數據這種需要申請連續空間的,如果空間比較大的,則會直接進入年老代。
在這裏插入圖片描述
在回收過程中,有一個參數比較重要,就是對象的年齡,如果在一次垃圾回收過程中有使用該對象的,則將對象年齡加1,否則減1,當計數爲0,則進行回收,如果年齡達到一定數字則進入老生代。總的來說內存分配機制主要體現在對象創建之後是否仍在使用,已經不使用的則回收,繼續使用的則對其年齡進行更新,達到一定程度,轉移到年老代。
二、垃圾回收算法
1.標記-清除算法
該算法先標記,後清除,將所有需要回收的算法進行標記,然後清除;這種算法的缺點是:效率比較低;標記清除後會出現大量不連續的內存碎片,這些碎片太多可能會使存儲大對象會觸發GC回收,造成內存浪費以及時間的消耗。

2.複製算法
複製算法將可用的內存分成兩份,每次使用其中一塊,當這塊回收之後把未回收的複製到另一塊內存中,然後把使用的清除。這種算法運行簡單,解決了標記-清除算法的碎片問題,但是這種算法代價過高,需要將可用內存縮小一半,對象存活率較高時,需要持續的複製工作,效率比較低。

3.標記整理算法
標記整理算法是針對複製算法在對象存活率較高時持續複製導致效率較低的缺點進行改進的,該算法是在標記-清除算法基礎上,不直接清理,而是使存活對象往一端遊走,然後清除一端邊界以外的內存,這樣既可以避免不連續空間出現,還可以避免對象存活率較高時的持續複製。這種算法適合老生代。

4.分代收集算法
分代收集算法就是目前虛擬機使用的回收算法,它解決了標記整理不適用於老年代的問題,將內存分爲各個年代,在不同年代使用不同的算法,從而使用最合適的算法,新生代存活率低,可以使用複製算法。而老年代對象存活率高,沒有額外空間對它進行分配擔保,所以使用標記整理算法。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章