6.3.5.3 迁移到新的内存管理器
3 分钟阅读
原文链接: https://kotlinlang.org/docs/native-migration-guide.html
6.3.5.3 迁移到新的内存管理器
注意: 对旧版内存管理器的支持已在 Kotlin 1.9.20 中完全移除。请把项目迁移到当前的内存模型,它从 Kotlin 1.7.20 起默认启用。
本指南比较新的 Kotlin/Native 内存管理器与旧版内存管理器,并说明如何迁移你的项目。
新内存管理器最显著的变化是取消了对对象共享的限制。你不再需要冻结对象才能在线程之间共享它们,具体来说:
- 顶层属性可以被任何线程访问和修改,而不需要使用
@SharedImmutable。 - 通过互操作传递的对象可以被任何线程访问和修改,而无需冻结它们。
Worker.executeAfter不再要求操作被冻结。Worker.execute不再要求生产者返回隔离的对象子图。- 包含
AtomicReference和FreezableAtomicReference的引用环不会导致内存泄漏。
除了轻松共享对象之外,新内存管理器还带来了其他重大变化:
- 全局属性会在首次访问其所在文件时惰性初始化。以前全局属性在程序启动时初始化。作为变通办法,你可以用
@EagerInitialization注解标记那些必须在程序启动时初始化的属性。使用前请先查看它的文档。 by lazy {}属性支持线程安全模式,并且不再处理无界递归。- 从
Worker.executeAfter中的operation逃逸出来的异常会像运行时其他部分一样处理:尝试执行用户定义的未处理异常钩子;如果没有找到该钩子,或钩子自身抛出异常,则终止程序。 - 冻结已被弃用,并且始终处于禁用状态。
请遵循以下准则把项目从旧版内存管理器迁移过来:
更新 Kotlin
新的 Kotlin/Native 内存管理器从 Kotlin 1.7.20 起默认启用。请检查 Kotlin 版本,如有必要就更新到最新版本。
更新依赖
kotlinx.coroutines
更新到 1.6.0 或更高版本。不要使用带 native-mt 后缀的版本。
对于新内存管理器,还有一些细节需要牢记:
- 每种常见的原语(通道、flow、协程)都能跨 Worker 边界工作,因为不再需要冻结。
Dispatchers.Default在 Linux 和 Windows 上由一组 Worker 支撑,在 Apple 目标上由全局队列支撑。- 使用
newSingleThreadContext创建一个由单个 Worker 支撑的协程调度器。 - 使用
newFixedThreadPoolContext创建一个由N个 Worker 组成的池支撑的协程调度器。 Dispatchers.Main在 Darwin 上由主队列支撑,在其他平台上由独立的 Worker 支撑。
Ktor
更新到 2.0 或更高版本。
其他依赖
大多数库应当无需任何改动即可工作,不过也可能有例外。 请确保把依赖更新到最新版本,并确保旧版与新内存管理器对应的库版本之间没有差异。
更新你的代码
为支持新的内存管理器,请移除下列受影响 API 的用法:
| 旧 API | 该怎么做 |
| @SharedImmutable | 你可以移除所有用法,不过在新内存管理器中使用该 API 不会有任何警告。 |
| The FreezableAtomicReference 类 | 改用 AtomicReference。 |
| The FreezingException 类 | 移除所有用法。 |
| The InvalidMutabilityException 类 | 移除所有用法。 |
| The IncorrectDereferenceException 类 | 移除所有用法。 |
| The freeze() 函数 | 移除所有用法。 |
| The isFrozen 属性 | 你可以移除所有用法。由于冻结已被弃用,该属性始终返回 false。 |
| The ensureNeverFrozen() 函数 | 移除所有用法。 |
| The atomicLazy() 函数 | 改用 lazy()。 |
| The MutableData 类 | 改用任意常规集合。 |
| The WorkerBoundReference<out T : Any> 类 | 直接使用 T。 |
| The DetachedObjectGraph<T> 类 | 直接使用 T。要通过 C 互操作传递该值,请使用 StableRef 类。 |