引用計數 vs. GC

內存管理問題

內存管理是編程過程當中的一個經典問題,早期在 C 語言時代,幾乎都靠 malloc/free 手動管理內存。隨着各個平臺的發展,到如今被普遍採用的主要有兩個方法:node

  • 引用計數 (ARC,Automatic Reference Counting)
  • GC (Garbage Collection)

管理方法 ARC/GC

由於 Java 的流行,GC 被普遍的認知。GC 簡單的說是按期查找再也不使用的對象,釋放對象佔用的內存。數據庫

基於 GC,申請的對象不須要手動釋放,只須要確認對象在再也不須要時,再也不被其餘對象引用。編程

引用計數早期主要用於底層系統,好比文件系統的 inode 管理,後來 C++ 的 boost 庫實現了一套完整的 ARC,目前流行的系統還有 Objective C 也是採用的 ARC。性能

ARC 的特色是,一個對象被引用時,引用計數增長 1,引用對象釋放時,引用計數減小 1,若是引用計數爲 0,釋放對象。spa

比較

由於 ARC 和 GC 的不一樣策略,對編程的幾個方面的影響。操作系統

性能

GC 須要一套額外的系統跟蹤分配的內存,分析哪些內存須要釋放,相對來講就須要更多的計算。這也是爲何對性能敏感的場景不採用 GC 的緣由,好比,高性能的服務端程序,資源有限的嵌入式設備(iOS 就沒有采用 GC)。指針

ARC 由開發者本身來管理資源在何時釋放,不須要額外的資源,因此性能沒有損失。code

延遲

GC 回收內存時,須要徹底暫停當前程序,這會給程序帶來難以預測的一個延遲期。若是須要回收的資源不少,這個延遲可能會很是大。對象

ARC 在資源引用爲 0 時當即釋放,沒有不可預測的延遲。進程

編程難度

不難看出,GC 在性能、延遲等方面有明顯的缺點,爲何 GC 還會被普遍採用呢?

GC 帶來的最大好處是不須要開發者手動管理內存分配,這大大下降了編程難度,同時能夠大幅減小跟內存管理相關的 Bug:

  • 懸空指針。指針指向的內存被其餘代碼釋放
  • 重複釋放內存
  • 內存泄漏。申請的內存沒釋放

不過使用 GC 並不表明能夠徹底不用理解內存管理,若是對象的引用關係跟想象的不一致,GC 也會有內存泄漏的問題

咱們以前理解的內存泄漏 是指一個分配的內存沒有被釋放形成的。而 GC 平臺下的內存泄漏是指對象有引用而開發者不知道,好比:

ObjectA -> ObjectB

ObjectB 使用完後,咱們沒有及時把 ObjectA 引用 ObjectB 的指針設置爲 NULL,這時, ObjectB 不會被 GC 回收。

  • 對比表格
  時機 性能 延遲 編程難度
ARC 引用計數爲 0 立刻回收 較大
GC 定時掃描清理 較小

怎麼選擇 ARC or GC

開發一個項目時,採用什麼樣的平臺,跟實際面對的場景有很大關係,沒有一個技術是用來解決全部問題的。

通常來講,對延遲和性能不敏感的系統,能夠考慮帶 GC 的平臺,好比 Java、Go 等來開發,一般能夠提升開發效率。

若是須要對系統的性能有良好的控制,或者平臺的資源有限,ARC 是更好的選擇。好比操做系統、數據庫等選擇 C 或者 C++。好比 iOS 的 Object C 就是採用 ARC,實際來看比使用 Java (GC) 的 Android 平臺的表現要好太多。

可是 ARC 平臺通常對開發者要求要更高。

最近出現的新語言 Rust 採用的是 ARC,可是 Rust 會在代碼編譯階段對內存、指針的使用作嚴格的分析和檢查,確保程序沒有內存管理問題。至關於把 GC 的一部分工做移到編譯階段,這樣程序的運行性能幾乎沒有損失,同時又大大減小內存管理相關的 Bug。

個人觀察從 C++11 正式吸納 boost 的 smart pointer 後,C++ 在內存管理方面比以前有極大的提高,若是嚴格的按照 smart pointer 的規範,一樣能夠減小內存管理的風險。Rust 就有點像一個嚴格的 C++11 編譯系統。

支持 GC 的平臺裏面有一個特殊的,就是 Erlang。Erlang 的 GC 是進程級別的(Erlang 的輕量級進程),意味着 GC 發生時,只暫停當前進程,其餘進程不受影響。另外,Erlang 程序每每會運行海量的進程,至關於把 GC 分散開了,因此 Erlang 的 GC 通常不會產生明顯的延遲。

瞭解這些細節,在面對具體問題時,能幫你作出正確的選擇。

歡迎來微博留下您的意見:http://weibo.com/2255454164/E48lBE9pU

 

weibo: @Tiger_張虎, 雲巴 (yunba.io) 創始人,yunba.io 雲端實時消息服務。 JPush 創始人,原CTO。 Oracle VM 創始團隊成員。

相關文章
相關標籤/搜索