[英]Kotlin Worker Pool - Long Running Kotlin Coroutine and Java Heap OutOfMemory
我正在尝试在 Kotlin 中复制一个工作池: https ://gobyexample.com/worker-pools
它工作得很好,但我的问题是我得到 OutOfMemoryError 因为只要协程正在运行,来自工作协程的所有对象引用都保存在堆中。 我怎样才能避免这个问题?
这是我的代码:
我在服务 A 中创建一个通道,并在每次收到通道对象时接收数据。
class ServiceA(
) {
val channel = Channel<Pair<String,ByteArray>>(10000)
private val coroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Default)
@PostConstruct
fun createWorkerGroup(){
coroutineScope.launch{
for(x in 1..5){
launch {
println("Create Worker $x")
while (true){
uploadImage(channel.receive() )
}
}
}
}
}
private suspend fun uploadImage(urlAndImage: Pair<String, ByteArray>){
val (url,image) = urlAndImage
println("Uploading Image: $url")
}
在我的控制器方法中,我将数据发送到通道:
uploadService.channel.send(Pair(url, image.bytes))
工作池可以由协程范围使用适当的调度程序自动处理。
如果图像上传执行阻塞操作,您可能需要使用 IO 调度程序,如下所示: CoroutineScope(Dispatchers.IO.limitedParallelism(5))
。 我省略了SupervisorJob
,因为您不需要它用于将在createWorkerGroup()
中创建的父协程,而是用于由它创建的父协程。 不要忘记创建不再需要时取消CoroutineScope
的逻辑。
之后,您可以在没有性能开销的情况下随意启动协程,就像您之前所做的那样:
@PostConstruct
fun createWorkerGroup() {
coroutineScope.launch{
supervisorScope {
channel.consumeEach {
launch {
uploadImage(it)
}
}
}
}
}
这是创建和使用工作池的正确方法,但您需要对其进行测试以查看它是否消除了OutOfMemoryError
。 您可能还想尝试减少通道的容量。 祝你好运!
谢谢@Halex 的帮助,这是我的 Kotlin 协程工作池,带有适当的垃圾收集
private val coroutineScope = CoroutineScope(Dispatchers.Default)
@OptIn(ExperimentalCoroutinesApi::class)
private val superVisorScope = CoroutineScope(SupervisorJob() + Dispatchers.IO.limitedParallelism(5))
@PostConstruct
fun createWorkerGroup() {
coroutineScope.launch {
superVisorScope.launch {
channel.consumeEach {
launch {
uploadImage(it)
}
}
}
}
coroutineScope.cancel()
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.