前面有說到堆的可用內存少於預期值。這與GC的算法有關,被其貪掉了。 算法
GC主要是對堆的內存進行管理,用到的算法有 對象
1.標記算法: 內存
實現分爲兩個階段,一:標記階段; 二:清除階段。經過根標記全部可達對象;在清除階段時清除沒有標記的對象。 基礎
這就堆區分活動對象與非活動對象的方式。 垃圾回收
2.複製算法: 時間
將內存空間分爲兩塊,每次只使用其中一塊,在垃圾回收時將存活對象複製到未使用的內存中,以後清除正在使用的內存(全部的對象)。這時這兩塊內存的角色就互換了,然後交替重複。這就是爲何新生代分爲eden,s0,s1.並且s0與s1同樣。而且系統會保留一個用來角色互換。s0和s1也稱爲survivor空間 vi
3.標記壓縮法: 壓縮
在標記算法基礎上添加了對內存的整理,由於若是單純的刪除會產生不少的零碎。因此對內存進行了整理,使其能夠連續。在老年代中用到 實例
4.分代算法: 管理
將內存區間根據對象分紅幾塊(堆中分紅新生代與老年代)。根據每塊內存區間的特色使用不一樣的回收算法
5.分區算法:
將整個堆空間劃分紅連續的不一樣小區間。每一個小區間都獨立使用。這種算法是能夠控制一次回收多少的空間。由於若是堆空間越大,那麼GC一次所要的時間就越長,從而產生停頓也就越長。分區會減小GC所產生的停頓
最後的歸總:
新生代中: 在eden先標記活動對象 -> 將活動對象複製到s0/s1中,清空eden -> 標記s0/s1的活動對象 ->複製到老年代中,清除s0/s1。
全部將建立的實例都在新生代中。新生代回收的頻率是很高的,但每次回收耗時都很短。
老年代中:標記活動對象 -> 清除非活動對象 -> 整理老年代中的空間
在通過屢次GC後還存活下來的實例把它放到老年代中,老年代回收次數少,且耗時長。