首页 > 解决方案 > Kotlin - 在迁移到 Kotlin 1.3 后,协程会导致 DefaultDispatcher 占用大量 CPU

问题描述

长期使用高并发下的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.

我的问题是:

  1. 为什么它会花费如此多的 CPU 使用率DefaultDispatcher
  2. 为什么默认使用 kotlin 1.3DefaultDispatcher代替ForkJoinPool.commonPool()
  3. 如何保持协程的行为就像 1.3 之前一样?

标签: kotlincoroutinejava.util.concurrentkotlin-coroutines

解决方案


  1. 为什么它会花费如此多的 CPU 使用率DefaultDispatcher

这是一个完全不同的实现,可以针对多个性能目标进行优化,例如通过通道进行通信。它有待于未来的改进。

  1. 为什么默认使用 kotlin 1.3DefaultDispatcher代替ForkJoinPool.commonPool()

其实一直都在用Defaultdispatcher,只是分辨率Default变了。在实验阶段,它等于,CommonPool但现在它更喜欢自定义实现。

  1. 如何保持协程的行为就像 1.3 之前一样?

kotlinx.coroutines.scheduler系统属性设置为off


推荐阅读