許多 C 或者 C++ 程序員對垃圾回收嗤之以鼻,認為垃圾回收肯定比自己來治理動態內存要低效,而且在回收的時候一定會讓程序停頓在那裡,而假如自己控制內存治理的話,分配和釋放時間都是穩定的,不會導致程序停頓。最後,很多 C/C++ 程序員堅信在C/C++ 中無法實現垃圾回收機制。這些錯誤的觀點都是由於不了解垃圾回收的算法而臆想出來的。
其實垃圾回收機制並不慢,甚至比動態內存分配更高效。因為我們可以只分配不釋放,那麼分配內存的時候只需要從堆上一直的獲得新的內存,移動堆頂的指針就夠了;而釋放的過程被省略了,自然也加快了速度。現代的垃圾回收算法已經發展了很多,增量收集算法已經可以讓垃圾回收過程分段進行,避免打斷程序的運行了。而傳統的動態內存治理的算法同樣有在適當的時間收集內存碎片的工作要做,並不比垃圾回收更有優勢。
而垃圾回收的算法的基礎通常基於掃描並標記當前可能被使用的所有內存塊,從已經被分配的所有內存中把未標記的內存回收來做的。C/C++ 中無法實現垃圾回收的觀點通常基於無法正確掃描出所有可能還會被使用的內存塊,但是,看似不可能的事情實際上實現起來卻並不復雜。首先,通過掃描內存的數據,指向堆上動態分配出來內存的指針是很輕易被識別出來的,假如有識別錯誤,也只能是把一些不是指針的數據當成指針,而不會把指針當成非指針數據。這樣,回收垃圾的過程只會漏回收掉而不會錯誤的把不應該回收的內存清理。其次,假如回溯所有內存塊被引用的根,只可能存在於全局變量和當前的棧內,而全局變量(包括函數內的靜態變量)都是集中存在於 bss 段或 data段中。
垃圾回收的時候,只需要掃描 bss 段, data 段以及當前被使用著的棧空間,找到可能是動態內存指針的量,把引用到的內存遞歸掃描就可以得到當前正在使用的所有動態內存了。
假如肯為你的工程實現一個不錯的垃圾回收器,提高內存治理的速度,甚至減少總的內存消耗都是可能的。假如有愛好的話,可以搜索一下網上已有的關於垃圾回收的論文和實現了的庫,開拓視野對一個程序員尤為重要。