無需 Unsafe 程式碼的垃圾回收機制
我開發了 safe-gc 函式庫,這是一個完全不使用 unsafe 程式碼的 Rust 垃圾回收器,透過利用 Rust 的所有權與借用機制,並結合基於 Arena 的索引方式,證明了在不犧牲安全性的情況下實現 GC 的可能性。
背景
在 Rust 社群中,實現垃圾回收(GC)庫通常被認為必須依賴 unsafe 代碼,以處理循環引用、追蹤物件邊緣以及繞過借用檢查器的限制。開發者們普遍追求的是提供一個「安全的外殼」來封裝內部的危險操作,但 safe-gc 專案挑戰了這一共識,透過將物件存儲在基於 Vec 的 Arena 空間中,並以索引取代指標,成功在完全禁用 unsafe 的情況下實現了功能完備的 GC 機制。
社群觀點
對於這項實驗性的嘗試,社群普遍將其視為一個極具啟發性的「概念驗證」,證明了 Rust 的安全子集確實具備構建複雜記憶體管理系統的能力。支持者認為這為那些極度排斥 unsafe 的專案提供了一條新路徑,特別是在處理複雜的圖狀結構或需要頻繁分配與釋放物件的場景下,這種做法能有效規避潛在的記憶體安全漏洞。然而,社群也敏銳地指出,這種安全性是以犧牲開發體驗與效能為代價的。
在開發體驗方面,有評論指出將所有受管轄的類型都必須包裝在 Gc<T> 中,會導致類型系統與特定的 GC 分配器深度耦合。這意味著開發者若想嘗試引入 GC,必須對現有的資料結構進行大規模重構,且必須手動實現 Trace 特性,這增加了不少開發負擔。此外,關於效能與記憶體佈局的討論也相當熱烈。部分留言者分析,由於無法使用 unsafe 進行底層的記憶體操作,safe-gc 在處理空閒列表時必須使用標籤化聯合體(如 Option),這會導致額外的記憶體對齊開銷。雖然有建議指出可以透過 NonZero 類型來優化索引空間以消除 Option 標籤,但整體而言,這種基於索引的存取模式在指令快取與分支預測上的表現,仍難以與傳統的指標操作匹敵。
此外,社群中也出現了關於 Rust 安全邊界的反思。有觀點認為,即便在 Rust 層面消除了 unsafe,底層的類型系統漏洞或編譯器缺陷仍可能威脅安全性。但對於大多數應用開發者來說,這種純粹的實踐確實降低了維護成本。也有開發者分享了類似的替代方案,例如在處理 C 語言外部函數介面(FFI)時,透過建立合法指標的映射表來驗證傳入的原始指標,這種做法與 safe-gc 的索引查表邏輯異曲同工,都是試圖在不穩定的邊界上建立一道由安全 Rust 守護的防線。
延伸閱讀
- cve-rs: 留言中提到的一個專案,旨在展示如何利用 Rust 類型系統中的漏洞來觸發記憶體不安全行為,提醒開發者即便不使用
unsafe關鍵字,仍需對類型安全保持警覺。
相關文章
其他收藏 · 0