淺議C++中的垃圾回收方法

字號:

許多 C 或者 C++ 程序員對垃圾回收嗤之以鼻,認(rèn)為垃圾回收肯定比自己來管理動態(tài)內(nèi)存要低效,而且在回收的時候一定會讓程序停頓在那里,而如果自己控制內(nèi)存管理的話,分配和釋放時間都是穩(wěn)定的,不會導(dǎo)致程序停頓。最后,很多 C/C++ 程序員堅信在C/C++ 中無法實(shí)現(xiàn)垃圾回收機(jī)制。這些錯誤的觀點(diǎn)都是由于不了解垃圾回收的算法而臆想出來的。
    其實(shí)垃圾回收機(jī)制并不慢,甚至比動態(tài)內(nèi)存分配更高效。因?yàn)槲覀兛梢灾环峙洳会尫牛敲捶峙鋬?nèi)存的時候只需要從堆上一直的獲得新的內(nèi)存,移動堆頂?shù)闹羔樉蛪蛄?;而釋放的過程被省略了,自然也加快了速度?,F(xiàn)代的垃圾回收算法已經(jīng)發(fā)展了很多,增量收集算法已經(jīng)可以讓垃圾回收過程分段進(jìn)行,避免打斷程序的運(yùn)行了。而傳統(tǒng)的動態(tài)內(nèi)存管理的算法同樣有在適當(dāng)?shù)臅r間收集內(nèi)存碎片的工作要做,并不比垃圾回收更有優(yōu)勢。
    而垃圾回收的算法的基礎(chǔ)通常基于掃描并標(biāo)記當(dāng)前可能被使用的所有內(nèi)存塊,從已經(jīng)被分配的所有內(nèi)存中把未標(biāo)記的內(nèi)存回收來做的。C/C++ 中無法實(shí)現(xiàn)垃圾回收的觀點(diǎn)通?;跓o法正確掃描出所有可能還會被使用的內(nèi)存塊,但是,看似不可能的事情實(shí)際上實(shí)現(xiàn)起來卻并不復(fù)雜。首先,通過掃描內(nèi)存的數(shù)據(jù),指向堆上動態(tài)分配出來內(nèi)存的指針是很容易被識別出來的,如果有識別錯誤,也只能是把一些不是指針的數(shù)據(jù)當(dāng)成指針,而不會把指針當(dāng)成非指針數(shù)據(jù)。這樣,回收垃圾的過程只會漏回收掉而不會錯誤的把不應(yīng)該回收的內(nèi)存清理。其次,如果回溯所有內(nèi)存塊被引用的根,只可能存在于全局變量和當(dāng)前的棧內(nèi),而全局變量(包括函數(shù)內(nèi)的靜態(tài)變量)都是集中存在于 bss 段或 data段中。
    垃圾回收的時候,只需要掃描 bss 段, data 段以及當(dāng)前被使用著的??臻g,找到可能是動態(tài)內(nèi)存指針的量,把引用到的內(nèi)存遞歸掃描就可以得到當(dāng)前正在使用的所有動態(tài)內(nèi)存了。
    如果肯為你的工程實(shí)現(xiàn)一個不錯的垃圾回收器,提高內(nèi)存管理的速度,甚至減少總的內(nèi)存消耗都是可能的。如果有興趣的話,可以搜索一下網(wǎng)上已有的關(guān)于垃圾回收的論文和實(shí)現(xiàn)了的庫,開拓視野對一個程序員尤為重要。