從記憶體管理策略看Rust獨特性 - Khorchanov

banq發表於2021-12-27

我是一名 Java 開發人員,我知道在開發關鍵的安全應用程式時使用這種語言的主要優點和缺點。每個人接近 Java 的主要內容是它的 GC(又名垃圾收集器)。最早提出開箱即用的自動記憶體管理的語言是它。還有許多其他語言使用 GC、Javascript、Golang、python……

在 Rust 之前,語言只有兩種策略來處理記憶體管理。但現在我們有三個。

 

1. 讓開發人員手工處理記憶體分配和釋放

從歷史上看,這是第一種方法。C 就是一個很好的例子。有了 malloc 和 free 兩個過程,開發者可以計算出自己需要的記憶體,手動分配,不需要的時候再釋放。為開發人員提供此功能並不是免費的,在具有複雜程式碼庫的大型應用程式中,任何人都可以:

  • 為所需資料分配錯誤大小
  • 忘記在應該釋放記憶體的時候
  • 釋放記憶體,引入另一種稱為懸空指標的問題,從而訪問壞記憶體導致安全問題。

但是,在高效能是關鍵的許多情況下,賦予開發人員手動處理記憶體的能力有時是完美的,例如實時應用程式,因為我們為 GC 演算法消除了相當多的執行時執行時間以自動釋放未使用的記憶體(GC 帶有暫停......) .

 

2. 自動記憶體管理

背後的想法是讓開發人員建立邏輯並讓另一個系統處理記憶體分配和釋放。這提高了此類程式的安全性,不再是:指標操作、手動記憶體分配、懸空指標、訪問錯誤記憶體地址……我們可以構建不易出錯的系統,開發人員最終可以專注於核心功能而不是技術指標算術。

這個系統被稱為垃圾收集器,它是為了解決上述問題而出現的。但很快就會帶來各種效能下降,Java 的 VM 會暫停。然後我們有許多實現隨著時間的推移逐漸提高效能。Java 17 中的shenandoah是高效能 GC 的最佳示例。

 

3. Rust 模式:混合

 rust 提出了另一種方法:我們可以自動管理記憶體,但同時避免讓觀察者增加執行時的開銷嗎?是的,Rust 編譯器。在編譯時,它會計算空閒記憶體的放置位置,命名為drop函式,並將其放置在原始碼中應位於的位置,所有這些都在編譯之前。這要歸功於借用檢查器

變數由擁有它的“上下文”實現管理,並且隨著時間的推移,變數的所有權可以可從“上下文”轉移或借用給另一個“上下文”,一旦變數的所有者不在範圍內,變數的最後一個所有者負責釋放其記憶體。

Rust 解決了另一個問題,使用切片懸掛指標,通過將所有變數設定為預設的不可變狀態來實現併發。

 

相關文章