Kotlin - 在迁移到 Kotlin 1.3 后,协程导致 DefaultDispatcher 大量使用 CPU
Kotlin - Coroutines cause heavy CPU usage with DefaultDispatcher after migration to Kotlin 1.3
我长期使用高并发下的Kotlin协程实验版,性能一直很优秀。主要逻辑可以简化为以下代码:
// works fine in kotlin 1.2 with 3000+ QPS for a 40-core host
launch {
// running in ForkJoinPool.commonPool() by default
// non-blocking IO function
val result = supendFunction()
doSomething(result)
}
但是,我把kotlin更新到1.3,迁移到正式版协程后,是这样的
// kotlin 1.3 version
GlobalScope.launch {
// running in DefaultDispatcher
// non-blocking IO function
val result = supendFunction()
doSomething(result)
}
CPU 使用率从 2% 上升到 50%,没有任何异常或错误抛出。我注意到的唯一区别是协程不再像以前那样在 ForkJoinPool.commonPool()
中执行。相反,它们在 DefaultDispatcher
个线程中 运行,例如 DefaultDispatcher-worker-30
.
我的问题是:
- 为什么 CPU 与
DefaultDispatcher
的使用成本如此之高?
- 为什么kotlin 1.3默认使用
DefaultDispatcher
代替ForkJoinPool.commonPool()
?
- 如何保持协程的行为与 1.3 之前一样?
- Why does it cost so much CPU usage with
DefaultDispatcher
?
这是一个完全不同的实现,针对多个性能目标进行了优化,例如通过通道进行通信。它会在未来进行改进。
- Why does kotlin 1.3 use
DefaultDispatcher
in place of ForkJoinPool.commonPool()
by default?
其实一直在用Default
调度器,只是Default
的分辨率变了。在实验阶段,它等于 CommonPool
但现在它更喜欢自定义实现。
- How to keep the behavior of coroutines just like before 1.3?
将 kotlinx.coroutines.scheduler
系统 属性 设置为 off
。
我长期使用高并发下的Kotlin协程实验版,性能一直很优秀。主要逻辑可以简化为以下代码:
// works fine in kotlin 1.2 with 3000+ QPS for a 40-core host
launch {
// running in ForkJoinPool.commonPool() by default
// non-blocking IO function
val result = supendFunction()
doSomething(result)
}
但是,我把kotlin更新到1.3,迁移到正式版协程后,是这样的
// kotlin 1.3 version
GlobalScope.launch {
// running in DefaultDispatcher
// non-blocking IO function
val result = supendFunction()
doSomething(result)
}
CPU 使用率从 2% 上升到 50%,没有任何异常或错误抛出。我注意到的唯一区别是协程不再像以前那样在 ForkJoinPool.commonPool()
中执行。相反,它们在 DefaultDispatcher
个线程中 运行,例如 DefaultDispatcher-worker-30
.
我的问题是:
- 为什么 CPU 与
DefaultDispatcher
的使用成本如此之高? - 为什么kotlin 1.3默认使用
DefaultDispatcher
代替ForkJoinPool.commonPool()
? - 如何保持协程的行为与 1.3 之前一样?
- Why does it cost so much CPU usage with
DefaultDispatcher
?
这是一个完全不同的实现,针对多个性能目标进行了优化,例如通过通道进行通信。它会在未来进行改进。
- Why does kotlin 1.3 use
DefaultDispatcher
in place ofForkJoinPool.commonPool()
by default?
其实一直在用Default
调度器,只是Default
的分辨率变了。在实验阶段,它等于 CommonPool
但现在它更喜欢自定义实现。
- How to keep the behavior of coroutines just like before 1.3?
将 kotlinx.coroutines.scheduler
系统 属性 设置为 off
。