1. 程式人生 > >Delphi中ARC內存管理的方向

Delphi中ARC內存管理的方向

程序 維護 monk -c 會有 混合 win 傳統 .org

隨著即將發布的10.3版本,RAD Studio R&D和PM團隊正在制作Delphi在內存管理方面的新方向。


幾年前,當Embarcadero開始為Windows以外的平臺構建新的Delphi編譯器時,就核心語言功能和語言的整體感知而言,有很多討論新Delphi與當前語言的兼容性。最終出現的決定是保持極高程度的兼容性,並采用一些重要而大膽的步驟來實現更能吸引新一代開發人員的語言。

什麽是自動參考計數?

技術分享圖片

(具有弱引用的交叉鏈接對象)

其中一個變化就是決定采用新的移動平臺內存管理模式,遵循Apple已經推出的iOS內存模式:自動引用計數或ARC在使用垃圾收集的移動電話這樣的內存受限設備上通常被認為是一個問題(因為您最終消耗的內存比嚴格需要的內存多,並且還會影響電池壽命)並且ARC提供了簡化的內存管理模型,更易於使用在簡單的場景中,完全確定性和健壯性。

這就是為什麽Delphi選擇相同的模型,擴展對象引用計數模型已經可用於接口很長一段時間了,使得它更強大的弱和不安全的引用,並將其擴展為普通的對象變量。該模型確實提供了一些顯著的優勢,其中一個最初的想法是在所有平臺上將其擴展為Delphi語言。

ARC缺點

技術分享圖片

(纏繞弱和強引用)

在計劃推出幾年後,我們仍然看到它的優勢和好處,但我們對ARC模型的缺點以及它在Windows和VCL應用程序中使其成為默認值的效果更加清晰。 。

我們長期以來一直認為ARC內存管理是對傳統Delphi模型的改進,因為它消除並簡化了一些內存管理。但是,我們在構建和維護大型庫時,以及在復雜的代碼庫上與客戶交談時已經學到了這一點,雖然ARC在紙上看起來很棒,對於局部變量和更簡單的場景,但它往往會給復雜場景帶來很多麻煩。

我們所有庫的TComponent所有權模型都與ARC不一致,使得支持ARC的現有組件庫變得復雜。
我們本可以決定在Windows上使用“完全ARC”,但這會導致現有應用程序和組件的嚴重破壞,造成比我們過去的Unicode遷移更多的麻煩 - 這是由於外部壓力造成的提供良好的國際支持以及底層操作系統(從Windows開始)也是Unicode的事實。

我們有許多要求使ARC成為可選項,但是一個啟用ARC的對象不會輕易與非啟用ARC的對象共存,我們需要兩種對象的容器,並且無法混合它們。這最終將成為一個非常復雜的場景。混合ARC和非ARC不是一個可行的解決方案,但是在不同平臺上保持不同的內存模型最終會擊敗“單一來源,多平臺”的整個想法,這是當今Delphi服務器端的核心原則(Windows和Linux)和所有平臺上的客戶端站點都可以構建FireMonkey應用程序。

另一個重要的角度是ARC具有運行時成本。雖然可以對事物進行優化和改進,但最終自動管理並非完全免費。雖然垃圾收集在開始時具有(非常高的)成本,但ARC在對象生命周期和對象交互方面有成本(除非您小心地將const用於所有參數傳遞)。禁用ARC的積極效果是可衡量的性能改進。最後,Delphi中的ARC與產品的C ++方面有點不一致,後者是RAD Studio不可或缺的一部分。

新計劃:逐步淘汰ARC

技術分享圖片 技術分享圖片

(在Delphi中使用接口)

考慮到所有這些因素,經過廣泛的內部討論,還涉及合作夥伴和外部開發人員,我們得出的結論是,最好的方法是將ARC模型作為默認的內存管理解決方案,並彌補其損失與其他選擇。

實際上,10.3 Rio版本中Linux 64位編譯器將提供Windows平臺的傳統Delphi內存管理,使您的Windows和Linux服務器端代碼完全等效 - 至少在Delphi語言和內存方面管理。

前進的計劃是不接受ARC用於即將推出的macOS 64位平臺(因此所有桌面平臺都將保留在非ARC模型上)並且將來也禁用ARC用於移動平臺(很可能是在10.3)之後的下一個主要版本。請註意,在10.3 Rio中,移動編譯器仍然啟用了ARC,與10.2完全相同。

現代記憶管理還有什麽?

技術分享圖片

(來源:https//pixabay.com/photo-1751201/

我們仍然認為引用計數內存管理是相關的,但我們更願意利用和擴充Delphi中接口和字符串使用的現有引用計數模型,而不是為它引入新機制。這種情況已經存在了很長時間。如果處理不當,接口引用和對同一對象的對象引用會引起麻煩,但這是大多數Delphi開發人員已經知道如何處理的問題,並且有很多關於該主題的文檔。

最近使用弱引用甚至不安全的引用擴展了接口引用。這些附加選項大大增加了“ARC for interfaces”的功能和靈活性。換句話說,雖然我們要刪除ARC以進行對象引用,但是用於接口引用的ARC是已經並將繼續可用的語言的一個特性。

除此之外,我們希望改進和簡化具有堆棧引用的本地短期對象的生命周期(和內存管理)的管理。這是我們將在10.3中引入的一個非功能,但我們正在積極研究這些功能,並且可以由開發人員利用托管記錄(10.3中的新語言功能)部分實現。

包起來

技術分享圖片

(內存泄漏跟蹤變得簡單)

雖然我們知道幾年前對計劃的這種改變可能會令人驚訝並影響現有代碼,開發人員對ARC模型不滿意,支持不同平臺上的多個模型,以及與本機內存管理相比性能損失,很可能會欣賞這個決定。

提供進一步簡化Delphi內存管理的替代方法是在RAD Studio的路線圖中,但當前的一組功能(具有引用計數和支持弱和不安全引用,組件所有權模型和標準通用實踐的接口)已經提供了一個很好的框架減少Delphi開發人員對手動內存管理的擔憂。

最終,編程語言中沒有完美的內存管理解決方案,因為自動編程語言有其缺點,而手動編程語言(手動)也是如此。德爾福在過去一直保持著良好的平衡,這種平衡今天仍在繼續,並且將來只會有所改善。

http://blog.marcocantu.com/blog/2018-october-Delphi-ARC-directions.html

Delphi中ARC內存管理的方向