内存模型演进
源:Memory Management Evolution - Kotlin/Native
Kotlin/Native 的内存模型经历了从严格线程隔离到现代 GC 的重大演进。理解这段历史有助于迁移遗留代码。
传统内存模型 (Legacy MM)已废弃
###设计理念
传统模型基于 严格的线程隔离 和 对象冻结:
kotlin
// 传统模型的核心概念
class DataHolder(var value: Int)
fun legacyThreading() {
val data = DataHolder(42)
// 在主线程修改
data.value = 100 // ✅ OK
// 跨线程共享前必须冻结
data.freeze()
// ❌ 冻结后无法修改
// data.value = 200 // InvalidMutabilityException
// Worker 线程
Worker.start().execute(TransferMode.SAFE, { data }) {
// 只能读取冻结的对象
println(it.value) // OK: 100
}
}freeze() 机制
kotlin
@OptIn(FreezingIsDeprecated::class)
import kotlin.native.concurrent.*
class MutableState {
var counter = 0
val list = mutableListOf<String>()
}
fun demonstrateFreeze() {
val state = MutableState()
// 冻结前
state.counter++ // ✅ 可修改
state.list.add("item") // ✅ 可修改
// 冻结
state.freeze()
// 冻结后
println(state.isFrozen) // true
println(state.counter) // ✅ 可读取
// state.counter++ // ❌ InvalidMutabilityException
// state.list.add("item2") // ❌ InvalidMutabilityException
}TransferMode
kotlin
@OptIn(ObsoleteWorkersApi::class)
enum class TransferMode {
// 安全模式:自动冻结对象
SAFE,
// 不安全模式:不执行检查(开发者自己保证安全)
UNSAFE
}
fun useTransferMode() {
val data = DataHolder(42)
// SAFE:Worker.execute 自动冻结 data
Worker.start().execute(TransferMode.SAFE, { data }) {
// it 是冻结的
println(it.isFrozen) // true
}
}传统模型的问题
主要局限性
- 学习曲线陡峭 - 开发者需要掌握冻结机制
- 共享困难 - 可变对象无法跨线程共享
- 性能开销 - 频繁的对象拷贝
- 内存泄漏 - 循环引用引起泄漏
- 与 JVM 差异大 - 跨平台代码难以维护
kotlin
// ❌ 传统模型的痛点
class LegacyPainPoint {
fun complexSharing() {
val data = mutableMapOf<String, MutableList<Int>>()
data["key"] = mutableListOf(1, 2, 3)
// 要跨线程共享需要:
// 1. 冻结整个对象图
data.freeze()
// 2. 无法再修改
// data["key"]?.add(4) // 错误!
// 3. 如果需要修改,必须拷贝
val workerData = data.toMutableMap() // 深拷贝
// 性能开销大
}
}新内存模型 (New MM)Kotlin 1.7.20+
核心特性
新模型带来了现代垃圾回收:
kotlin
// 新模型:自由共享
class ModernThreading {
fun simpleSharing() {
val counter = AtomicInt(0)
val list = mutableListOf<String>()
// ✅ 直接跨线程共享,无需冻结
repeat(10) {
Thread {
counter.incrementAndGet()
synchronized(list) {
list.add("Item $it")
}
}.start()
}
Thread.sleep(100)
println("Counter: ${counter.value}")
println("List size: ${list.size}")
}
}GC 算法
kotlin
@OptIn(ExperimentalStdlibApi::class)
import kotlin.native.runtime.GC
fun exploreNewGC() {
// 新 GC 是并发标记-清除收集器
// 手动触发 GC
GC.collect()
// 安排 GC(非阻塞)
GC.schedule()
// 获取 GC 信息
val info = GC.lastGCInfo
if (info != null) {
println("GC pause: ${info.pauseTimeNs / 1_000_000.0}ms")
println("Memory freed: ${info.freedBytes / 1024}KB")
println("Objects freed: ${info.freedObjectsCount}")
}
}对象共享
kotlin
@OptIn(FreezingIsDeprecated::class)
// ❌ 传统:需要冻结
class LegacyCache {
private val cache = mutableMapOf<String, String>()
init {
freeze() // 整个对象冻结
}
fun get(key: String): String? {
return cache[key] // 只能读
}
// 无法实现 put,因为对象已冻结
}kotlin
// ✅ 新模型:直接共享 + 同步
class ModernCache {
private val cache = mutableMapOf<String, String>()
private val lock = Any()
fun get(key: String): String? {
return synchronized(lock) {
cache[key]
}
}
fun put(key: String, value: String) {
synchronized(lock) {
cache[key] = value
}
}
}迁移指南
检查 Kotlin 版本
kotlin
// build.gradle.kts
// ✅ 新内存模型:1.7.20+
kotlin("multiplatform") version "1.9.20"
// ❌ 旧版本需升级
// kotlin("multiplatform") version "1.6.21"移除 freeze 调用
kotlin
@OptIn(FreezingIsDeprecated::class)
class Before {
private val data = MyData()
init {
data.freeze() // ❌ 删除这行
}
fun share(): MyData {
return data.freeze() // ❌ 删除 freeze()
}
}kotlin
// ✅ 直接共享,添加必要的同步
class After {
@Volatile
private var data = MyData()
fun share(): MyData {
return data
}
fun update(newData: MyData) {
data = newData // @Volatile 保证可见性
}
}替换 Worker API
kotlin
@OptIn(ObsoleteWorkersApi::class)
import kotlin.native.concurrent.Worker
// ❌ 旧 API
fun oldWay() {
val worker = Worker.start()
val future = worker.execute(TransferMode.SAFE, { input }) {
processData(it)
}
val result = future.result
worker.requestTermination().result
}kotlin
import kotlinx.coroutines.*
// ✅ 新方式:使用协程
suspend fun newWay() = withContext(Dispatchers.Default) {
val result = async {
processData(input)
}
result.await()
}更新依赖
kotlin
// build.gradle.kts
dependencies {
// ❌ 旧版本(native-mt 后缀)
// implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2-native-mt")
// ✅ 新版本(无后缀)
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3")
}移除注解
kotlin
// ❌ 删除这些注解
@SharedImmutable // 不再需要
val globalData = listOf(1, 2, 3)
@ThreadLocal // 根据实际需求保留或删除
var threadData = 0修改全局初始化
kotlin
// 传统模型:全局变量立即初始化
val heavyObject = ExpensiveComputation() // 启动时执行
// 新模型:默认延迟初始化
val heavyObject = ExpensiveComputation() // 首次访问时执行
// 如需立即初始化
@EagerInitialization
val eagerObject = ExpensiveComputation() // 启动时执行性能对比
对象创建
| 操作 | Legacy MM | New MM | 提升 |
|---|---|---|---|
| 简单对象创建 | 100ns | 80ns | 1.25x |
| 跨线程传递 | 300ns (冻结+拷贝) | 50ns (直接共享) | 6x |
| 大对象共享 (1MB) | 5ms (深拷贝) | 0.1ms (引用) | 50x |
GC 暂停时间
| 堆大小 | Legacy STW | New MM并发 GC | 改善 |
|---|---|---|---|
| 10MB | 5ms | 2ms | 2.5x |
| 100MB | 50ms | 8ms | 6.25x |
| 1GB | 500ms | 30ms | 16.7x |
并发性能
kotlin
// 性能测试:1000 次并发写入
@OptIn(ExperimentalTime::class)
import kotlin.time.measureTime
fun benchmarkConcurrency() {
val threads = 10
val iterations = 100
val duration = measureTime {
val counter = AtomicInt(0)
List(threads) {
Thread {
repeat(iterations) {
counter.incrementAndGet()
}
}
}.forEach { it.start(); it.join() }
}
println("Completed in: ${duration.inWholeMilliseconds}ms")
// Legacy MM: ~500ms (因为冻结/拷贝)
// New MM: ~50ms (直接共享)
}最佳实践
实践:使用原子类型
kotlin
import kotlinx.atomicfu.*
// ✅ 线程安全的计数器
class SafeCounter {
private val _count = atomic(0)
val count: Int
get() = _count.value
fun increment() {
_count.incrementAndGet()
}
}实践:合理使用同步
kotlin
// ✅ 细粒度锁
class OptimizedCache {
private val cache = ConcurrentHashMap<String, String>()
fun get(key: String) = cache[key]
fun put(key: String, value: String) = cache.put(key, value)
}
// ✅ 读写锁
class RWLockCache {
private val cache = mutableMapOf<String, String>()
private val lock = ReentrantReadWriteLock()
fun get(key: String): String? {
lock.read {
return cache[key]
}
}
fun put(key: String, value: String) {
lock.write {
cache[key] = value
}
}
}新内存模型极大简化了 Kotlin/Native 的并发编程。迁移工作量相对较小,但收益显著。建议所有新项目直接使用新模型,旧项目尽快迁移。