迁移到新的内存管理器
最终更新: 2024/03/21
本向导会对新的 Kotlin/Native 内存管理器 与旧的内存管理器进行比较, 并介绍如何迁移你的项目.
新内存管理器最重要的变化是解除了对象共享的限制. 在线程之间共享对象时, 你不需要冻结对象, 具体来说:
- 顶层属性不需要标注
@SharedImmutable
, 可以被任意线程访问和修改. - 通过代码交互传递的对象不需要冻结, 可以被任意线程访问和修改.
Worker.executeAfter
不再要求其中的操作被冻结.Worker.execute
不再需要生成者返回一个孤立的对象子图(subgraph).- 包含
AtomicReference
和FreezableAtomicReference
的环形引用不会导致内存泄露.
除了对象共享更加容易之外, 新的内存管理器还带来了其他主要变化:
- 全局属性会在定义它们的文件被初次访问时延迟执行它们的初始化. 以前全局属性会在程序启动时初始化.
作为一个变通方法, 你可以使用
@EagerInitialization
注解, 将属性标注为必须在程序启动时初始化. 使用这个注解之前, 请先阅读它的 文档. by lazy {}
属性支持线程安全模式, 而且不处理无限递归.- 从
Worker.executeAfter
的operation
中抛出的异常, 会和运行时的其它部分一样进行处理, 尝试执行一个用户自定义的、未被处理的异常处理程序, 如果没有找到异常处理程序, 或异常处理程序自身也抛出异常而失败, 则终止程序. - 冻结功能已被废弃, 默认禁用, 会在将来的发布版中删除. 如果你不需要你的代码在 旧的内存管理器 下工作, 请不要使用冻结.
要从旧的内存管理器迁移你的项目, 请遵循下面的步骤:
更新 Kotlin
从 Kotlin 1.7.20 开始会默认启用新的 Kotlin/Native 内存管理器. 请检查 Kotlin 版本, 如果需要的话, 请 更新到最新版.
更新依赖项
kotlinx.coroutines |
更新到 1.6.0 或更高版本. 不要使用带 关于新内存管理器, 还有一些需要注意的问题: Dispatchers.Default 在 Linux 和 Windows 上通过 Worker 池来实现, 在 Apple 目标平台上则通过全局队列来实现.newSingleThreadContext 来创建依靠单个 Worker 实现的协程派发器.newFixedThreadPoolContext 来创建依靠 N 个 Worker 的池实现的协程派发器.Dispatchers.Main 在 Darwin 上依靠主队列实现, 在其它平台依靠独立的 Worker 来实现. |
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 类. |
同时支持新的和旧的内存管理器
如果你是库的作者, 需要维护你的代码支持旧的内存管理器, 或者在新的内存管理器出现问题时希望能够回退到旧的内存管理器, 你可以临时的支持新的和旧的内存管理器.
要忽略编译器的废弃警告, 请进行以下任何一种操作:
- 使用已废弃的 API 时添加
@OptIn(FreezingIsDeprecated::class)
注解. - 在 Gradle 中, 对所有的 Kotlin 源代码集添加
languageSettings.optIn("kotlin.native.FreezingIsDeprecated")
. - 传递编译器选项
-opt-in=kotlin.native.FreezingIsDeprecated
.
详情请参见 明确要求使用者同意的功能.