title: JVM學習筆記——GC概述
date: 2018/9/2 12:05:00
description: 最近開始着手JVM的學習,在這裏把本身學習過程當中的筆記分享出來,但願能幫到一些小夥伴,同時也是對本身的學習的一個梳理。java
其實GC主要就是思考如下三件事情:算法
a.instance = b; b.instance = a;
使用GC Roots做爲起始點,當一個對象到GC Roots沒有引用鏈路時(即不可達),則此時對象視爲「死亡」。此方法也是現有JVM中經常使用的算法。
GC Roots包括下面幾種:學習
- 虛擬機棧(棧幀中的本地變量表)中引用的對象
- 本地方法棧中Native方法引用的對象
- 方法區中類靜態屬性引用的對象
- 方法區中常量引用的對象
換句話來講,以上4中類型其實就是:類成員變量,類靜態變量,常量,局部變量,只要某個對象不被以上4種類型關聯到,那麼該對象就是「已死」的,gc時就會被回收內存空間。指針
針對標記-清除的效率問題,複製算法將內存分爲兩塊空間,每次只使用其中一塊。當這塊的內存空間用完時,將存活的對象移到另外一塊中,而後將已使用的內存空間一次性清理掉。這樣作的好處是不會產生碎片,清除也是針對連續的空間作處理,只要移動堆指針就行。
實際上在如今的虛擬機中,將這種算法應用在新生代。按照8:1:1的比例將內存分爲三塊,每次使用一塊較大的與較小的其中一塊,清理時將存活對象移到剩下的一塊中,這樣每次只會浪費10%的內存,因爲新生代中的內存通常都是「朝生夕死」的,使用這種算法能夠極大的提高效率。可是,不能保證每次清理時,剩下的一塊空間可以存放全部的存活對象,因此這裏會依賴其餘內存空間(通常指老年代)進行分配擔保(Handle Promotion)。code
複製算法在對象存活率較高時,效率就會變低,因此針對高對象存活率的狀況,就有人提出了該算法。標記的過程並無變化,但標記後並非進行「清除」,而是將存活的對象向一端進行移動整理,而後清除掉其他的空間。現代虛擬機常將這種算法在老年代中使用。對象
分代收集算法是根據對象的存活時間,將內存劃分幾塊(通常分爲新生代和老年代),這樣就能夠根據不一樣的內存區域特色採用不一樣的算法。針對新生代,使用複製算法,用少許的內存空間換來更大的效率;針對老年代,使用標記-整理或標記-清除來處理。ip