JVM中四種GC算法案例詳解
介紹
程序在運(yùn)行過(guò)程中,會(huì)產(chǎn)生大量的內(nèi)存垃圾(一些沒(méi)有引用指向的內(nèi)存對(duì)象都屬于內(nèi)存垃圾,因?yàn)檫@些對(duì)象已經(jīng)無(wú)法訪問(wèn),程序用不了它們了,對(duì)程序而言它們已經(jīng)死亡),為了確保程序運(yùn)行時(shí)的性能,java虛擬機(jī)在程序運(yùn)行的過(guò)程中不斷地進(jìn)行自動(dòng)的垃圾回收(GC)。關(guān)于 JVM 的 GC 算法主要有下面四種:
引用計(jì)數(shù)算法(Reference counting)
算法思想:
每個(gè)對(duì)象在創(chuàng)建的時(shí)候,就給這個(gè)對(duì)象綁定一個(gè)計(jì)數(shù)器。每當(dāng)有一個(gè)引用指向該對(duì)象時(shí),計(jì)數(shù)器加一;每當(dāng)有一個(gè)指向它的引用被刪除時(shí),計(jì)數(shù)器減一。這樣,當(dāng)沒(méi)有引用指向該對(duì)象時(shí),該對(duì)象死亡,計(jì)數(shù)器為0,這時(shí)就應(yīng)該對(duì)這個(gè)對(duì)象進(jìn)行垃圾回收操作。
核心思想:
為每個(gè)對(duì)象額外存儲(chǔ)一個(gè)計(jì)數(shù)器 RC ,根據(jù) RC 的值來(lái)判斷對(duì)象是否死亡,從而判斷是否執(zhí)行 GC 操作。
優(yōu)點(diǎn):
- 簡(jiǎn)單
- 計(jì)算代價(jià)分散
- “幽靈時(shí)間”短(幽靈時(shí)間指對(duì)象死亡到回收的這段時(shí)間,處于幽靈狀態(tài))
缺點(diǎn):
- 不全面(容易漏掉循環(huán)引用的對(duì)象)
- 并發(fā)支持較弱
- 占用額外內(nèi)存空間
例子如圖:
初始狀態(tài):
改變引用后:
標(biāo)記–清除算法(Mark-Sweep)
算法思想:
為每個(gè)對(duì)象存儲(chǔ)一個(gè)標(biāo)記位,記錄對(duì)象的狀態(tài)(活著或是死亡)。分為兩個(gè)階段,一個(gè)是標(biāo)記階段,這個(gè)階段內(nèi),為每個(gè)對(duì)象更新標(biāo)記位,檢查對(duì)象是否死亡;第二個(gè)階段是清除階段,該階段對(duì)死亡的對(duì)象進(jìn)行清除,執(zhí)行 GC 操作。
優(yōu)點(diǎn)
- 最大的優(yōu)點(diǎn)是,相比于引用計(jì)數(shù)法,標(biāo)記—清除算法中每個(gè)活著的對(duì)象的引用只需要找到一個(gè)即可,找到一個(gè)就可以判斷它為活的。
- 此外,這個(gè)算法相比于引用計(jì)數(shù)法更全面,在指針操作上也沒(méi)有太多的花銷(xiāo)。更重要的是,這個(gè)算法并不移動(dòng)對(duì)象的位置(后面?zhèn)z算法涉及到移動(dòng)位置的問(wèn)題)。
缺點(diǎn)
- 很長(zhǎng)的幽靈時(shí)間,判斷對(duì)象已經(jīng)死亡,消耗了很多時(shí)間,這樣從對(duì)象死亡到對(duì)象被回收之間的時(shí)間過(guò)長(zhǎng)。
- 每個(gè)活著的對(duì)象都要在標(biāo)記階段遍歷一遍;所有對(duì)象都要在清除階段掃描一遍,因此算法復(fù)雜度較高。
- 沒(méi)有移動(dòng)對(duì)象,導(dǎo)致可能出現(xiàn)很多碎片空間無(wú)法利用的情況。
例子如圖
這個(gè)圖中,圓圈內(nèi)灰色的對(duì)象就是已經(jīng)死亡的對(duì)象,被標(biāo)記為死亡,等待清除。
標(biāo)記–整理算法
算法思想
標(biāo)記-整理法是標(biāo)記-清除法的一個(gè)改進(jìn)版。同樣,在標(biāo)記階段,該算法也將所有對(duì)象標(biāo)記為存活和死亡兩種狀態(tài);不同的是,在第二個(gè)階段,該算法并沒(méi)有直接對(duì)死亡的對(duì)象進(jìn)行清理,而是將所有存活的對(duì)象整理一下,放到另一處空間,然后把剩下的所有對(duì)象全部清除。這樣就達(dá)到了標(biāo)記-整理的目的。
優(yōu)點(diǎn)
- 該算法不會(huì)像標(biāo)記-清除算法那樣產(chǎn)生大量的碎片空間。
缺點(diǎn)
- 如果存活的對(duì)象過(guò)多,整理階段將會(huì)執(zhí)行較多復(fù)制操作,導(dǎo)致算法效率降低。
例子
如圖:
上面是標(biāo)記階段,下面是整理之后的狀態(tài)。可以看到,該算法不會(huì)產(chǎn)生大量碎片內(nèi)存空間。
復(fù)制算法
算法思想
該算法將內(nèi)存平均分成兩部分,然后每次只使用其中的一部分,當(dāng)這部分內(nèi)存滿(mǎn)的時(shí)候,將內(nèi)存中所有存活的對(duì)象復(fù)制到另一個(gè)內(nèi)存中,然后將之前的內(nèi)存清空,只使用這部分內(nèi)存,循環(huán)下去。
注意:
這個(gè)算法與標(biāo)記-整理算法的區(qū)別在于,該算法不是在同一個(gè)區(qū)域復(fù)制,而是將所有存活的對(duì)象復(fù)制到另一個(gè)區(qū)域內(nèi)。
優(yōu)點(diǎn)
- 實(shí)現(xiàn)簡(jiǎn)單
- 不產(chǎn)生內(nèi)存碎片
缺點(diǎn)
- 每次運(yùn)行,總有一半內(nèi)存是空的,導(dǎo)致可使用的內(nèi)存空間只有原來(lái)的一半。
總結(jié)
不同算法有不同的優(yōu)點(diǎn)和缺點(diǎn),除了引用計(jì)數(shù)法不常用外,其他三種算法在現(xiàn)在的java虛擬機(jī)上也是很常見(jiàn)的,間接說(shuō)明了這幾個(gè)經(jīng)典算法還是有其適用性的。
理解 JVM 的 GC 算法能夠幫助我們更好地理解java的垃圾回收機(jī)制,例如,在 JVM 的年輕代使用的是復(fù)制算法來(lái)進(jìn)行垃圾回收(由于其中的存活對(duì)象比例較?。?;而在老年代,使用的卻是標(biāo)記-清除法或標(biāo)記-整理法(由于每次回收都只回收少量對(duì)象)
到此這篇關(guān)于JVM中四種GC算法案例詳解的文章就介紹到這了,更多相關(guān)JVM中四種GC算法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring Cloud下基于OAUTH2認(rèn)證授權(quán)的實(shí)現(xiàn)示例
這篇文章主要介紹了Spring Cloud下基于OAUTH2認(rèn)證授權(quán)的實(shí)現(xiàn)示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-03-03一文帶你詳細(xì)認(rèn)識(shí)文件與Java中操作文件
文件處理是任何應(yīng)用程序的重要部分,Java 提供了許多用于創(chuàng)建、讀取、更新和刪除文件的方法,這篇文章主要給大家介紹了關(guān)于認(rèn)識(shí)文件與Java中操作文件的相關(guān)資料,需要的朋友可以參考下2024-05-05springAop實(shí)現(xiàn)講解(看這篇夠了)
AOP面向切面編程是一種編程范式,它通過(guò)將通用的橫切關(guān)注點(diǎn)(如日志、事務(wù)、權(quán)限控制等)與業(yè)務(wù)邏輯分離,使得代碼更加清晰、簡(jiǎn)潔、易于維護(hù),這篇文章主要介紹了springAop實(shí)現(xiàn)講解(看這篇夠了),需要的朋友可以參考下2024-02-02Java+Swing實(shí)現(xiàn)經(jīng)典五子棋游戲
五子棋是世界智力運(yùn)動(dòng)會(huì)競(jìng)技項(xiàng)目之一,是一種兩人對(duì)弈的純策略型棋類(lèi)游戲,是世界智力運(yùn)動(dòng)會(huì)競(jìng)技項(xiàng)目之一。本文將采用Java Swing實(shí)現(xiàn)這一經(jīng)典游戲,需要的可以參考一下2022-01-01Java使用黑盒方式模擬實(shí)現(xiàn)內(nèi)網(wǎng)穿透
這篇文章主要介紹了Java使用黑盒方式模擬實(shí)現(xiàn)內(nèi)網(wǎng)穿透,內(nèi)網(wǎng)穿透,也即 NAT 穿透,進(jìn)行 NAT 穿透是為了使具有某一個(gè)特定源 IP 地址和源端口號(hào)的數(shù)據(jù)包不被 NAT 設(shè)備屏蔽而正確路由到內(nèi)網(wǎng)主機(jī),需要的朋友可以參考下2023-05-05java算法題解LeetCode35復(fù)雜鏈表的復(fù)制實(shí)例
這篇文章主要為大家介紹了java算法題解LeetCode35復(fù)雜鏈表的復(fù)制實(shí)例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01