簡體   English   中英

Kotlin Worker Pool - 長時間運行的 Kotlin 協程和 Java 堆 OutOfMemory

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM