JVM——垃圾回收(GC)
GC簡單介紹
java語言執行在java虛擬機(jvm)上。為了解決有限的空間和性能的保證這個矛盾體,jvm所具備的GC能力。能夠有效的清除不用的對象。使空間的利用更加合理。以下介紹該機制的原理。
推斷對象已廢棄
- 引用計數法
給每個對象都配備一個計數器,對於該對象,若添加一個指向它的引用,則計數器加1。每失效一個引用。則計數器減一。
可是,假設兩個對象互相引用,但都對於外部都已失去用途,則這種兩個對象是無法被計數為0的,由於他們的計數器永遠都僅僅為1。 - 可達性分析法
為了解決引用計數法的缺陷,我們引入可達性分析。
從引用鏈的頂端root開始,僅僅要在這條引用鏈上的對象都是實用的,因此不應該被回收。而對於剩下的對象,一定是不可到達的對象,也就沒什麽意義了。
怎樣釋放沒用的對象空間
標記清除
將廢棄的對象空間標記出來,直接清除就可以。
可是。這樣會造成空間的碎片過多。假設有較大的對象須要空間,則會有更大的可能,它無法找到這種空間。
復制法
將堆空間分為兩塊,最好還是叫做from和to。每次new對象的時候。先放在from上,(to塊保持空暇),直到from區域放滿。這是要進行垃圾回收,將存活的對象拷貝到 to上,然後清空from區域,並將from和to進行互換,又一次開始。
缺點是,總有一部分空間要充當to區域,因此該區域總是空暇著等待交換。造成內存的浪費。標記整理
相似於標記清楚,僅僅只是是在標記之後不是簡單的清除,而是將存貨對象整理好。一個一個排在一起。讓後釋放剩下的連續的一整塊空間。這樣做的壞處是。須要對全部對象進行復制移動,比較耗時。分代處理
將堆內存區分為Eden區,survivorFrom區、surviorTo區(以上三個都屬於年輕代),老年代和永久代。- 當新建對象的時候通常是首先放在年輕代的Eden和surviorFrom中,當滿了之後,將存活對象放入survivorTo中(及MinorGC),放不下的直接放入年老代。互換survivor的from和to區。
- 當老年代也滿了之後。將執行一整個的大清洗FullGC,將全部堆內存(除了永久代)進行一次完整的GC。
- 永久代是不會在主程序執行期間進行GC的。永久代主要存放Class類信息。
JVM——垃圾回收(GC)