遷移至新的記憶體管理員
Kotlin 1.9.20 已完全移除對舊版記憶體管理員的支援。請將您的專案遷移至目前的記憶體模型,該模型自 Kotlin 1.7.20 起已預設啟用。
本指南比較了新的 Kotlin/Native 記憶體管理員與舊版管理員的差異,並說明如何遷移您的專案。
新的記憶體管理員最顯著的變化是解除了物件共享的限制。您不需要凍結物件就能在執行緒之間共享它們,具體包括:
- 最上層屬性可以由任何執行緒存取和修改,無需使用
@SharedImmutable。 - 透過互操作性(interop)傳遞的物件可以由任何執行緒存取和修改,無需凍結它們。
Worker.executeAfter不再要求操作必須被凍結。Worker.execute不再要求產製者傳回隔離的物件子圖。- 包含
AtomicReference和FreezableAtomicReference的參照循環不會導致記憶體洩漏。
除了更容易共享物件外,新的記憶體管理員還帶來了其他重大變化:
- 全域屬性會在首次存取其定義所在的檔案時延遲初始化。以前全域屬性是在程式啟動時初始化的。作為暫時解決方案,您可以使用
@EagerInitialization註解標記必須在程式啟動時初始化的屬性。在使用之前,請查閱其文件。 by lazy {}屬性支援執行緒安全模式,且不處理無限制的遞迴。- 在
Worker.executeAfter中從operation逃逸的例外處理方式與執行時的其他部分相同:嘗試執行使用者定義的未處理例外攔截器,如果找不到攔截器或攔截器本身執行失敗並拋出例外,則終止程式。 - 凍結已棄用且一律停用。
請遵循以下指南將您的專案從舊版記憶體管理員遷移:
更新 Kotlin
新的 Kotlin/Native 記憶體管理員自 Kotlin 1.7.20 起已預設啟用。請檢查 Kotlin 版本,必要時更新至最新版本。
更新相依性
更新至 1.6.0 或更高版本。請勿使用帶有 native-mt 字尾的版本。
關於新的記憶體管理員,還有一些細節您應該留意:
- 由於不再需要凍結,每個通用基本型別(channels、flows、coroutines)都能跨 Worker 邊界運作。
Dispatchers.Default在 Linux 和 Windows 上由 Worker 池支援,在 Apple 目標平台上則由全域佇列支援。- 使用
newSingleThreadContext來建立由 Worker 支援的協程分派器(coroutine dispatcher)。 - 使用
newFixedThreadPoolContext來建立由N個 Worker 组成的池所支援的協程分派器。 Dispatchers.Main在 Darwin 上由主佇列支援,在其他平台上則由獨立的 Worker 支援。
大多數程式庫應該無需任何更改即可運作,但可能存在例外。
請確保將相依性更新至最新版本,且舊版與新版記憶體管理員的程式庫版本之間沒有差異。
更新您的程式碼
若要支援新的記憶體管理員,請移除受影響 API 的用法:
| 舊版 API | 該做什麼 |
|---|---|
@SharedImmutable | 您可以移除所有用法,儘管在新的記憶體管理員中使用此 API 不會有警告。 |
FreezableAtomicReference 類別 | 改用 AtomicReference。 |
FreezingException 類別 | 移除所有用法。 |
InvalidMutabilityException 類別 | 移除所有用法。 |
IncorrectDereferenceException 類別 | 移除所有用法。 |
freeze() 函式 | 移除所有用法。 |
isFrozen 屬性 | 您可以移除所有用法。由於凍結已棄用,該屬性一律傳回 false。 |
ensureNeverFrozen() 函式 | 移除所有用法。 |
atomicLazy() 函式 | 改用 lazy()。 |
MutableData 類別 | 改用任何常規集合。 |
WorkerBoundReference<out T : Any> 類別 | 直接使用 T。 |
DetachedObjectGraph<T> 類別 | 直接使用 T。若要透過 C 互操作性傳遞值,請使用 StableRef 類別。 |
