DEV Community

Batcave
Batcave

Posted on

newSingleThreadContext() causes outofmemoryexeception in my service on Android

I am using newSingleThreadContext() to create a work and a arch threads. And I get outofmemory exception.

Here is the code : "sampleId" is called everytime we change a parameter and this is implemented to throttle spamming of parameters to a test-library. Where we execute parameters sequentially instead of parallel.

package com.my.app.extension

import com.my.app.datastore.ParamValue
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock

suspend fun Flow.waitForTrue(stateFlow: StateFlow): Flow {
return flow {
stateFlow.first { it }
this@waitForTrue.collect(this)
}
}

/**

  • Sample unique id and only return after a waiting time defined
  • @param periodMillis The time we wait to return if we get lots of calls in ms
  • @param waitMillis The time before next execution in ms
    */
    @DelicateCoroutinesApi
    fun Flow>.sampleId(
    periodMillis: Long,
    waitMillis: Long = 100
    ): Flow> =
    channelFlow {
    val hashMap = hashMapOf>>()
    var hasBeenActivated = false
    var activated = false
    var task: Deferred? = null
    val mutex = Mutex()

    fun process() {
        if (!hasBeenActivated) {
            hasBeenActivated = true
            launch(newSingleThreadContext("work")) {
                while (activated) {
                    delay(periodMillis)
                    mutex.withLock {
                        // hashmap operations.
                    }
                }
                hasBeenActivated = false
            }
        }
    }
    
    launch(newSingleThreadContext("arch")) {
        collect { item ->
            activated = true
            task?.cancel()
            task = async {
                delay(waitMillis)
                activated = false
            }
            mutex.withLock {
                item.second?.let {
                    // hashmap operations.
                }
            }
            process()
        }
    }
    

    }

I have tried to use different APIs of kotlin-android like newSingleThreadExecutor().asCoroutineDispatcher(), also used "use" call to free up the resource used like this

val context = newSingleThreadContext("worker")
context.use {
launch(context) {
But for some reason those parameter updates are not sent to the test-library at all.

I need some kind of mechanism where I do not get this outofmemory exception(by releasing threads after each iteration or something) and also the parameter updates are sent to the test-library.

Top comments (0)