什么是垃圾收集器?有什么作用?
java同C,C++相比有一個顯著區(qū)別,就是java中自帶垃圾回收器雇寇,這樣創(chuàng)建的java對象所有占用的內(nèi)存就不需要java開發(fā)人員自己關(guān)心去釋放內(nèi)存!而C++開發(fā)人員需要自己手動釋放!
垃圾回收器常用的算法及實驗原理
1.引用計數(shù)法 (Reference Counting)
實現(xiàn)原理就是每個對象都有一個自己的計數(shù)器锨侯,當(dāng)有一個變量引用時嫩海,計數(shù)器就會加1,失去引用就會減1囚痴;正如對象A有三個變量引用他叁怪,所以計數(shù)器就為3;
缺點:當(dāng)對象之間互相引用時深滚,會導(dǎo)致垃圾對象不能進行回收奕谭,內(nèi)存空間無法釋放!
如圖:
如果對象A痴荐,B沒有其他別的對象引用血柳,A,B就成為了垃圾對象生兆,但是由于互相引用在垃圾收集時還無法回收掉难捌;這樣就導(dǎo)致A,B對象一直無法釋放所占用的內(nèi)存鸦难!
2.標(biāo)記-清除算法 (Mark-Sweep)
實現(xiàn)原理就是在垃圾收集之前根吁,先對內(nèi)存中的對象進行標(biāo)記(有引用或無引用),然后對無引用的對象進行清除~
缺點:由于清除不能保證是連續(xù)清除合蔽,所以在清除對象后會產(chǎn)生大量的碎片击敌;就好比裁縫做衣服,如果沒有合理的規(guī)劃裁剪布料拴事,就導(dǎo)致剩下的碎布料什么也做不了了沃斤,就浪費了~~~生活中的道理都是大同小異~O(∩_∩)O哈哈~我太聰明了!<菲浮!
3.標(biāo)記-壓縮算法 (Mark-Compact)
原理和標(biāo)記捅彻,清除差不多组去,唯一的不同的就是標(biāo)記清除不會產(chǎn)生碎片嘛?這個又多做了一步步淹,對內(nèi)存空間又重新進行了整理从隆,這樣就導(dǎo)致碎片空間變成整塊的空間了~
4.復(fù)制算法 (Copying)
可能你看到這里,你會有一個疑問缭裆,為啥給分來了键闺??澈驼?對~這個就是復(fù)制算法的特點辛燥,首先他會把內(nèi)存分成兩半,然后用其中的一半,當(dāng)垃圾回收時會把有引用的對象復(fù)制到另一半內(nèi)存中(在復(fù)制期間還可以重新調(diào)整空間挎塌,不會產(chǎn)生碎片空間)徘六,然后把之前用的那一半內(nèi)存直接釋放出來~
缺點:就是可用內(nèi)存變小了~因為他分成了兩半~~~~
5.增量算法 (Incremental Collecting)
在垃圾回收過程中,應(yīng)用軟件將處于一種 CPU 消耗很高的狀態(tài)榴都。在這種 CPU 消耗很高的狀態(tài)下待锈,應(yīng)用程序所有的線程都會掛起,暫停一切正常的工作嘴高,等待垃圾回收的完成竿音。如果垃圾回收時間過長,應(yīng)用程序會被掛起很久拴驮,將嚴(yán)重影響用戶體驗或者系統(tǒng)的穩(wěn)定性春瞬。
增量算法的基本思想是,如果一次性將所有的垃圾進行處理莹汤,需要造成系統(tǒng)長時間的停頓快鱼,那么就可以讓垃圾收集線程和應(yīng)用程序線程交替執(zhí)行。每次纲岭,垃圾收集線程只收集一小片區(qū)域的內(nèi)存空間抹竹,接著切換到應(yīng)用程序線程。依次反復(fù)止潮,直到垃圾收集完成窃判。使用這種方式,由于在垃圾回收過程中喇闸,間斷性地還執(zhí)行了應(yīng)用程序代碼袄琳,所以能減少系統(tǒng)的停頓時間。但是燃乍,因為線程切換和上下文轉(zhuǎn)換的消耗唆樊,會使得垃圾回收的總體成本上升,造成系統(tǒng)吞吐量的下降刻蟹;
6.分代 (Generational Collecting)
根據(jù)垃圾回收對象的特性逗旁,不同階段最優(yōu)的方式是使用合適的算法用于本階段的垃圾回收,分代算法即是基于這種思想舆瘪,它將內(nèi)存區(qū)間根據(jù)對象的特點分成幾塊片效,根據(jù)每塊內(nèi)存區(qū)間的特點,使用不同的回收算法英古,以提高垃圾回收的效率淀衣。以Hot Spot虛擬機為例,它將所有的新建對象都放入稱為年輕代的內(nèi)存區(qū)域召调,年輕代的特點是對象會很快回收膨桥,因此蛮浑,在年輕代就選擇效率較高的復(fù)制算法。當(dāng)一個對象經(jīng)過幾次回收后依然存活国撵,對象就會被放入稱為老生代的內(nèi)存空間陵吸。在老生代中,幾乎所有的對象都是經(jīng)過幾次垃圾回收后依然得以幸存的介牙。因此壮虫,可以認(rèn)為這些對象在一段時期內(nèi),甚至在應(yīng)用程序的整個生命周期中环础,將是常駐內(nèi)存的囚似。如果依然使用復(fù)制算法回收老生代,將需要復(fù)制大量對象线得。再加上老生代的回收性價比也要低于新生代饶唤,因此這種做法也是不可取的。根據(jù)分代的思想贯钩,可以對老年代的回收使用與新生代不同的標(biāo)記-壓縮算法募狂,以提高垃圾回收效率。
從不同角度分析垃圾收集器角雷,可以將其分為不同的類型
1. 按線程數(shù)分祸穷,可以分為串行垃圾回收器和并行垃圾回收器。串行垃圾回收器一次只使用一個線程進行垃圾回收勺三;并行垃圾回收器一次將開啟多個線程同時進行垃圾回收雷滚。在并行能力較強的 CPU 上,使用并行垃圾回收器可以縮短 GC 的停頓時間吗坚。
2.按照工作模式分祈远,可以分為并發(fā)式垃圾回收器和獨占式垃圾回收器。并發(fā)式垃圾回收器與應(yīng)用程序線程交替工作商源,以盡可能減少應(yīng)用程序的停頓時間车份;獨占式垃圾回收器(Stop the world) 一旦運行,就停止應(yīng)用程序中的其他所有線程牡彻,直到垃圾回收過程完全結(jié)束扫沼。
3. 按碎片處理方式可分為壓縮式垃圾回收器和非壓縮式垃圾回收器。壓縮式垃圾回收器會在回收完成后讨便,對存活對象進行壓縮整理充甚,消除回收后的碎片以政;非壓縮式的垃圾回收器不進行這步操作霸褒。
4. 按工作的內(nèi)存區(qū)間,又可分為新生代垃圾回收器和老年代垃圾回收器盈蛮。
用以下指標(biāo)評價一個垃圾處理器的好壞
吞吐量:指在應(yīng)用程序的生命周期內(nèi)废菱,應(yīng)用程序所花費的時間和系統(tǒng)總運行時間的比值。系統(tǒng)總運行時間=應(yīng)用程序耗時+GC 耗時。如果系統(tǒng)運行了 100min殊轴,GC 耗時 1min衰倦,那么系統(tǒng)的吞吐量就是 (100-1)/100=99%。
垃圾回收器負(fù)載:和吞吐量相反旁理,垃圾回收器負(fù)載指來記回收器耗時與系統(tǒng)運行總時間的比值樊零。
停頓時間:指垃圾回收器正在運行時,應(yīng)用程序的暫停時間孽文。對于獨占回收器而言驻襟,停頓時間可能會比較長。使用并發(fā)的回收器時芋哭,由于垃圾回收器和應(yīng)用程序交替運行沉衣,程序的停頓時間會變短,但是减牺,由于其效率很可能不如獨占垃圾回收器豌习,故系統(tǒng)的吞吐量可能會較低。
垃圾回收頻率:指垃圾回收器多長時間會運行一次拔疚。一般來說肥隆,對于固定的應(yīng)用而言,垃圾回收器的頻率應(yīng)該是越低越好草雕。通常增大堆空間可以有效降低垃圾回收發(fā)生的頻率巷屿,但是可能會增加回收產(chǎn)生的停頓時間。
反應(yīng)時間:指當(dāng)一個對象被稱為垃圾后多長時間內(nèi)墩虹,它所占據(jù)的內(nèi)存空間會被釋放嘱巾。
堆分配:不同的垃圾回收器對堆內(nèi)存的分配方式可能是不同的。一個良好的垃圾收集器應(yīng)該有一個合理的堆內(nèi)存區(qū)間劃分诫钓。
JVM 垃圾回收器分類
新生代串行收集器
老年代串行收集器
并行收集器
新生代并行回收 (Parallel Scavenge) 收集器
老年代并行回收收集器
CMS 收集器
G1 收集器 (Garbage First)
以上收集器的特點與介紹請看原博客(已經(jīng)寫的很屌了):https://www.ibm.com/developerworks/cn/java/j-lo-JVMGarbageCollection/
參考博客:https://www.ibm.com/developerworks/cn/java/j-lo-JVMGarbageCollection/
以上是我在看完原作者博客的基礎(chǔ)上旬昭,基于我的理解畫了一些流程圖,方便別人理解~不對之處還請批評指正>取N示小!還有一些知識點我這里沒有寫惧所,想了解更多也請看原作者博客~~~