Skip to content

迁移到新的内存管理器

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

本指南将比较新的 Kotlin/Native 内存管理器与旧内存管理器,并描述如何迁移项目。

新内存管理器中最显著的变化是取消了对象共享的限制。你不再需要冻结对象即可在线程间共享它们,具体而言:

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

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

  • 全局属性在首次访问定义它们的文件时惰性初始化。以前,全局属性在程序启动时初始化。作为一种变通方法,你可以使用 @EagerInitialization 注解标记那些必须在程序启动时初始化的属性。使用前,请查阅其文档
  • by lazy {} 属性支持线程安全模式,但不处理无界递归。
  • Worker.executeAfter 中逃逸出 operation 的异常,像在其他运行时部分一样处理,即尝试执行用户定义的未处理异常钩子;如果未找到钩子或钩子本身执行失败并抛出异常,则终止程序。
  • 冻结已弃用,并且始终禁用。

请遵循以下指南,将项目从旧内存管理器迁移过来:

更新 Kotlin

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

更新依赖项

kotlinx.coroutines

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

新的内存管理器还有一些需要注意的特殊之处:

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

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

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

更新代码

为了支持新的内存管理器,请移除受影响的 API 用法:

旧 API操作
@SharedImmutable你可以移除所有用法,尽管在新内存管理器中使用此 API 不会有警告。
The FreezableAtomicReference class请改用 AtomicReference
The FreezingException class移除所有用法。
The InvalidMutabilityException class移除所有用法。
The IncorrectDereferenceException class移除所有用法。
The freeze() function移除所有用法。
The isFrozen property你可以移除所有用法。由于冻结已弃用,此属性始终返回 false
The ensureNeverFrozen() function移除所有用法。
The atomicLazy() function请改用 lazy()
The MutableData class请改用任何常规集合。
The WorkerBoundReference<out T : Any> class直接使用 T
The DetachedObjectGraph<T> class直接使用 T。要通过 C 互操作(interop)传递值,请使用 StableRef 类

接下来