[英]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.