bumble-tech / appyx

Model-driven navigation + UI components with gesture control for Compose Multiplatform
https://bumble-tech.github.io/appyx/
Apache License 2.0
1.13k stars 62 forks source link

Sample app memory leak #309

Open LachlanMcKee opened 1 year ago

LachlanMcKee commented 1 year ago

It seems like there may be a memory leak in the sample app. I have run it on an emulator running API 21 with very low specs.

The following is thrown after about 2 minutes of having the app open on the root screen (that loops through the animations of the samples):

Throwing OutOfMemoryError "Failed to allocate a 26460012 byte allocation with 4194304 free bytes and 12MB until OOM"
FATAL EXCEPTION: main
Process: com.bumble.appyx, PID: 8574
java.lang.IllegalArgumentException: Only VectorDrawables and rasterized asset types are supported ex. PNG, JPG
    at androidx.compose.ui.res.PainterResources_androidKt.loadImageBitmapResource(PainterResources.android.kt:111)
    at androidx.compose.ui.res.PainterResources_androidKt.access$loadImageBitmapResource(PainterResources.android.kt:1)
    at androidx.compose.ui.res.PainterResources_androidKt.painterResource(PainterResources.android.kt:70)
    at com.bumble.appyx.app.node.backstack.app.ChildNode.View(ChildNode.kt:37)
    at com.bumble.appyx.core.node.Node$Compose$1.invoke(Node.kt:134)
    at com.bumble.appyx.core.node.Node$Compose$1.invoke(Node.kt:132)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
    at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
    at com.bumble.appyx.core.node.Node.Compose(Node.kt:129)
    at com.bumble.appyx.core.composable.ChildRendererImpl.invoke(Child.kt:84)
    at com.bumble.appyx.core.composable.ComposableSingletons$ChildrenKt$lambda-1$1.invoke(Children.kt:35)
    at com.bumble.appyx.core.composable.ComposableSingletons$ChildrenKt$lambda-1$1.invoke(Children.kt:34)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:135)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
    at com.bumble.appyx.core.composable.ChildrenTransitionScope$children$1.invoke(Children.kt:95)
    at com.bumble.appyx.core.composable.ChildrenTransitionScope$children$1.invoke(Children.kt:94)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:149)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
    at com.bumble.appyx.core.composable.ChildKt$Child$1.invoke(Child.kt:57)
    at com.bumble.appyx.core.composable.ChildKt$Child$1.invoke(Child.kt:46)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
    at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
    at androidx.compose.runtime.saveable.SaveableStateHolderImpl.SaveableStateProvider(SaveableStateHolder.kt:84)
    at com.bumble.appyx.core.composable.ChildKt.Child(Child.kt:46)
    at com.bumble.appyx.core.composable.ChildrenTransitionScope._children(Children.kt:141)
    at com.bumble.appyx.core.composable.ChildrenTransitionScope.access$_children(Children.kt:66)
    at com.bumble.appyx.core.composable.ChildrenTransitionScope$_children$2.invoke(Children.kt)
    at com.bumble.appyx.core.composable.ChildrenTransitionScope$_children$2.invoke(Children.kt)
    at androidx.compose.runtime.RecomposeScopeImpl.compose(RecomposeScopeImpl.kt:145)
    at androidx.compose.runtime.ComposerImpl.recomposeToGroupEnd(Composer.kt:2375)
    at androidx.compose.runtime.ComposerImpl.skipCurrentGroup(Composer.kt:2643)
    at androidx.compose.runtime.ComposerImpl$doCompose$2$5.invoke(Composer.kt:3260)
    at androidx.compose.runtime.ComposerImpl$doCompose$2$5.invoke(Composer.kt:3238)
    at androidx.compose.runtime.SnapshotStateKt__DerivedStateKt.observeDerivedStateRecalculations(DerivedState.kt:341)
    at androidx.compose.runtime.SnapshotStateKt.observeDerivedStateRecalculations(Unknown Source)
    at androidx.compose.runtime.ComposerImpl.doCompose(Composer.kt:3238)
    at androidx.compose.runtime.ComposerImpl.recompose$runtime_release(Composer.kt:3203)
    at androidx.compose.runtime.CompositionImpl.recompose(Composition.kt:771)
    at androidx.compose.runtime.Recomposer.performRecompose(Recomposer.kt:1031)
    at androidx.compose.runtime.Recomposer.access$performRecompose(Recomposer.kt:125)
    at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$2.invoke(Recomposer.kt:534)
    at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$2.invoke
LachlanMcKee commented 1 year ago

While it says Only VectorDrawables and rasterized asset types are supported ex. PNG, JPG, I believe this is a red-herring as I can navigate through all the screens without issue. It just seems to happen when memory is low (when an image is being allocated)

Also, I think this may have been introduced via the Inside the backstack example, as I can get it to happen there more frequently.