compose-multiplatform: Memory leak in SnapshotStateObserver?
Hi JB team,
I’m trying to get up with a desktop app which updates small part of UI quite frequently (e.g. a timer). As result of app’s normal operation, memory consumption grows relatively quickly. Profiling points to SnapshotStateObserver
, which seem doesn’t release some state. However, I don’t see a way how to control that or set a limit.
After just half an hour of work, memory trend is clear:
On below screenshot you may see Live Bytes and Objects, the max numbers there constantly grow:
Sample app source:
import androidx.compose.material.Text
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.window.Window
import androidx.compose.ui.window.application
import kotlinx.datetime.Clock
import kotlin.concurrent.fixedRateTimer
fun main() = application {
remember {
fixedRateTimer(period = 50) { Holder.refreshClock() }
}
Window(onCloseRequest = ::exitApplication) {
Text(Holder.clock.value)
}
}
object Holder {
val clock = mutableStateOf(Clock.System.now().toString())
fun refreshClock() {
clock.value = Clock.System.now().toString()
}
}
OS: Manjaro Linux Compose: 1.1.0 OpenJDK: 11.0.15
Looking forward hearing back from you. Thanks!
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Reactions: 2
- Comments: 16 (1 by maintainers)
Commits related to this issue
- Add Gradle task to apply fix from https://github.com/JetBrains/compose-jb/issues/1969#issuecomment-1100604793 — committed to pema4/musicbx by pema4 2 years ago
- Fix memory leak in Update effects If there are animations on the screen, after some time we will encounter performance degradation, and an increased memory consumption. This fix is similar to the ot... — committed to JetBrains/compose-multiplatform-core by igordmn 2 years ago
- Fix memory leak in Update effects (#325) If there are animations on the screen, after some time we will encounter performance degradation, and an increased memory consumption. This fix is similar ... — committed to JetBrains/compose-multiplatform-core by igordmn 2 years ago
- Fix memory leak in Update effects (#325) If there are animations on the screen, after some time we will encounter performance degradation, and an increased memory consumption. This fix is similar ... — committed to JetBrains/compose-multiplatform-core by igordmn 2 years ago
- Fix memory leak in Update effects (#325) If there are animations on the screen, after some time we will encounter performance degradation, and an increased memory consumption. This fix is similar ... — committed to JetBrains/compose-multiplatform-core by igordmn 2 years ago
- Fix memory leak in Update effects (#325) If there are animations on the screen, after some time we will encounter performance degradation, and an increased memory consumption. This fix is similar ... — committed to JetBrains/compose-multiplatform-core by igordmn 2 years ago
- Fix memory leak in Update effects (#325) If there are animations on the screen, after some time we will encounter performance degradation, and an increased memory consumption. This fix is similar ... — committed to MatkovIvan/compose-multiplatform by igordmn 2 years ago
Thanks to all for investigating this issue! And especially @pema4 for the fix.
It is fixed, and the fix will be in 1.3.0 (or in 1.2.2, we will decide soon).
I believe the problem is in the
UpdateEffect
composableOn every invocation of the
performUpdate
snapshotObserver
is subscribed with new lambda object:I replaced this declaration with the following and the memory leak disappeared:
I posted the following already at the google issue tracker:
The memory leak is still present in Compose 1.2.0 with Kotlin 1.7.20. I profiled the code below (https://github.com/Ic-ks/compose-memory-leak) for 3 minutes with the Java Flight Recorder (the related .jfr file can be found here: https://issuetracker.google.com/action/issues/223222717/attachments/39334890?download=true). The overall allocated memory was more than 7GB. Heap usage steadily increased to 80 MB. It seems that
SnapshotStateObserver
does not clean its references properly.PS: .jfr files can be viewed with JDK Mission Control (https://github.com/openjdk/jmc)
Thanks for pointing at this issue, we’ll take a look.
There is a related bug report for Jetpack Compose: https://issuetracker.google.com/issues/223222717
This appears similar to a problem I have been investigating, though my problem occurs on Android with Jetpack Compose. Some details here
I think I may be experiencing the same issue. My app slows down after time, so I started the Intellij debug view. After running the app for some time I paused it and took a look at the memory usage. I can see that there are lots of allocations of
androidx.compose.runtime.collection.IdentityArraySet
. See screenshot:Is this expected? I am not sure. When looking at the stack trace of one of the objects I see the following: