有連線的表示可搭配使用 算法
第一階段:標記出可回收對象
第二階段:回收被標記的對象
缺點:產生大量的內存碎片
bash
內存被分爲相等的兩塊(S0+S1),S0爲使用內存,S1爲保留內存,回收時將S0的存活對象一次性所有複製到S1,再一次性清空S0內存
缺點:內存使用率只有50%
多線程
第一階段:標記出存活對象
第二階段:存活對象往一端移動,清理邊界外內存
併發
業界商用的JVM收集算法都是採用分代收集,按不一樣代的特色採用不一樣的收集算法。
一般狀況,年輕代採用複製算法,年老代採用標記-整理或標記-清除算法。
佈局
G1總體上看基於 "標記-整理" 算法,而兩個Region之間則基於 "複製" 算法
單線程串行收集器,垃圾收集時會「Stop The World」 spa
ParNew收集器就是Serial收集器的多線程版本,收集算法和回收策略和Serial徹底同樣,也會Stop The World。 注意:ParNew是並行收集器,不是併發收集器
線程
跟ParNew相似,是一種吞吐量優先
收集器,即目標是達到一個可控制的吞吐量3d
吞吐量 = 運行用戶代碼時間 / (運行用戶代碼時間) + 垃圾收集時間
複製代碼
Parallel Old是Parallel Scavenge收集器的老年代版本 code
CMS收集器是一種併發收集器,目標時已達到最小回收停頓時間,採用標記清除算法。 cdn
G1內存佈局中,保留了年輕代年老代的概念,但不是物理隔離,而是不少個大小相同的獨立區域(Region),年輕代和年老代都是一部分Region(不須要連續)的集合 初始標記:標記GC Roots能直接關聯到的對象 併發標記:從GC Roots中對堆對象進行可達性分析,找出存活對象 最終標記:修改併發期間變更的標記記錄 篩選回收:根據用戶指定的停頓時間制定回收計劃
無論是採用什麼樣的垃圾回收算法,都須要判斷對象的存活狀態,一般會採用兩種方式判斷
對象中增長一個引用計數器,每當有地方引用該對象時,其計數器+1,引用失效後計數器-1,當計數器爲0的對象,即認爲是可回收的對象,可是這種方式沒法解決循環引用的問題,因此目前主流的垃圾回收器都沒有采用這種方式。
經過GC Roots集合中的對象開始搜索,當某對象不能經過GCRoots到達時,斷定爲對象可回收。 對象一、二、三、4不可回收,對象五、六、7可回收
附一張以前畫過的JVM內存模型