Skip to content

迁移到新内存管理器

Kotlin 1.9.20 已完全移除对旧版内存管理器的支持。请将您的项目迁移到当前的内存模型,该模型自 Kotlin 1.7.20 起已默认启用。

本指南将新的 Kotlin/Native 内存管理器与旧版进行了对比,并说明了如何迁移您的项目。

新内存管理器中最显著的变化是取消了对象共享限制。您无需冻结 (freeze) 对象即可在线程间共享,具体包括:

  • 顶级属性可由任何线程访问和修改,无需使用 @SharedImmutable
  • 通过互操作 (interop) 传递的对象可由任何线程访问和修改,无需将其冻结。
  • Worker.executeAfter 不再要求操作必须被冻结。
  • Worker.execute 不再要求生产者返回孤立的对象子图。
  • 包含 AtomicReferenceFreezableAtomicReference 的引用循环不会导致内存泄漏。

除了更轻松的对象共享,新内存管理器还带来了其他重大变化:

  • 全局属性在首次访问其定义所在的文件时进行延迟初始化。以前,全局属性在程序启动时初始化。作为权宜之计,您可以使用 @EagerInitialization 注解标记必须在程序启动时初始化的属性。在使用之前,请查阅其文档
  • by lazy {} 属性支持线程安全模式,且不处理无限递归。
  • Worker.executeAfter 中从 operation 逃逸的异常处理方式与运行时其他部分一致:尝试执行用户定义的未处理异常挂钩,如果未找到该挂钩或其本身抛出异常,则终止程序。
  • 冻结 (Freezing) 已弃用并始终处于禁用状态。

请按照以下指南从旧版内存管理器迁移您的项目:

更新 Kotlin

新的 Kotlin/Native 内存管理器自 Kotlin 1.7.20 起已默认启用。请检查 Kotlin 版本,并在必要时更新到最新版本

更新依赖项

kotlinx.coroutines

更新到 1.6.0 或更高版本。不要使用带有 native-mt 后缀的版本。

关于新内存管理器,还有一些细节需要注意:

  • 由于不再需要冻结,所有常用原语(通道、流、协程)都可以跨越工作线程 (Worker) 边界工作。
  • Dispatchers.Default 在 Linux 和 Windows 上由工作线程池支持,在 Apple 目标平台上由全局队列支持。
  • 使用 newSingleThreadContext 创建由工作线程支持的协程调度器。
  • 使用 newFixedThreadPoolContext 创建由 N 个工作线程组成的池支持的协程调度器。
  • Dispatchers.Main 在 Darwin 上由主队列支持,在其他平台上由独立工作线程支持。
Ktor
更新到 2.0 或更高版本。
其他依赖项

大多数库应该无需任何更改即可工作,但可能存在例外。

请确保将依赖项更新到最新版本,且旧版和新版内存管理器的库版本之间没有差异。

更新您的代码

要支持新内存管理器,请移除受影响 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 类

下一步