l

    loloof64

    1 year ago
    It seems I am linking leaking memory in my
    @Composable
    , I know which part of code is responsible, but don't know exactly how to fix the issue. More on thread
    First, the full code of the
    @Composable
    . In next post, I'll post relevant part.
    d

    dewildte

    1 year ago
    Did you mean Leaking?
    l

    loloof64

    1 year ago
    Yes
    Colton Idle

    Colton Idle

    1 year ago
    Linking memory?
    Oh. Leaking.
    l

    loloof64

    1 year ago
    Here the relevant part. If I uncomment the section, memory keeps growing. (Noticed with the profiler tool) Here
    executeInstalledEngine
    is a long running task : hence the coroutine scope. But my implementation seems unefficient.
    My guess is that I have a kind of infinite loop : Recomposition -> Coroutine -> Recomposition -> Coroutine ..., but I can't be sure
    SelectEngineDialog
    is a wrapper around
    AlertDialog
    : if user click on item from its
    LazyColumn
    , a process is run in order to launch the selected chess engine.
    Zach Klippenstein (he/him) [MOD]

    Zach Klippenstein (he/him) [MOD]

    1 year ago
    Not sure what your bug is, reading code on slack on mobile is hard 😅 Two thoughts though:1. It looks like you've basically implemented a class inside your function. Might help readability to extract an actual class. Probably help testability too. 2. Passing an explicit
    CoroutineContext
    into a composable smells bad, and I’d bet your leak is probably related to that. All composable functions implicitly have their own coroutine scope, effectively, and that is the scope that should be used for coroutines launched from the composable - they will automatically be cancelled if the composable gets skipped.
    l

    loloof64

    1 year ago
    Thank you. I had the bad idea of sharing the
    CoroutineScope
    as I wanted to avoid to create two
    CoroutineScope
    for the parent, and its child. But it seems that's what I should do 🙂 So first, I try with creating two
    CoroutineScope
    instead of sharing.
    No it does not improve memory. So it should has something to do with long method
    executeInstalledEngine
    .
    This the class of instance
    currentRunner
    .
    Zach Klippenstein (he/him) [MOD]

    Zach Klippenstein (he/him) [MOD]

    1 year ago
    There are quite a few issues with that code, particularly around structured concurrency – too many to effectively review in a slack thread. I would start by reading up more on structured concurrency, and rethinking how you’re creating and using coroutine scopes.
    l

    loloof64

    1 year ago
    Indeed, I am a beginner in coroutine. I need a clear guidance 🙂. I still have to understand how to adapt and choose scopes, at least.
    Zach Klippenstein (he/him) [MOD]

    Zach Klippenstein (he/him) [MOD]

    1 year ago
    Sorry I can’t be more helpful – happy to help answer questions about structured concurrency in general, or specific code stuff, but this seems more like a design review and unfortunately i have a day job i need to get to 😅
    l

    loloof64

    1 year ago
    No problem. Thank you for your help anyway 🙂
    Gabriel Melo

    Gabriel Melo

    1 year ago
    Do you really need
    Context
    on that method? Retaining an instance of it after its provider has been destroyed is a frequent reason for leaks.
    If you really need it, try to separate the use of
    Context
    into another function that is not long-running and see if it improves things.
    References to
    Context
    ,
    Activity
    and
    Fragment
    are always dangerous in my experience.
    l

    loloof64

    1 year ago
    Hi @Gabriel Melo I use
    Context
    in order to access private folder of application
    Thank you, I understand why I get those Memory Leaks 🙂
    Indeed, I need to get the
    File
    instance from another method, a short-lived one 🙂
    Or better, pass the
    File
    object as a parameter : and
    PackageManager
    for some other methods.
    Thank you : the memory leak issue is solved
    I keep getting Garbage Collector messages in the logcat. So I have to stop application before it runs into OOM error
    Gabriel Melo

    Gabriel Melo

    1 year ago
    What is the message?
    l

    loloof64

    1 year ago
    I/art: Background partial concurrent mark sweep GC freed 5010(5MB) AllocSpace objects, 447(8MB) LOS objects, 16% free, 19MB/23MB, paused 1.478ms total 100.939ms
    I/art: Background partial concurrent mark sweep GC freed 4994(5MB) AllocSpace objects, 449(8MB) LOS objects, 16% free, 20MB/24MB, paused 1.459ms total 107.312ms
    I/art: Background partial concurrent mark sweep GC freed 5237(5MB) AllocSpace objects, 475(9MB) LOS objects, 16% free, 20MB/24MB, paused 1.534ms total 104.432ms
    I/art: Background partial concurrent mark sweep GC freed 5345(6MB) AllocSpace objects, 492(9MB) LOS objects, 16% free, 20MB/24MB, paused 1.542ms total 112.015ms
    I/art: Background partial concurrent mark sweep GC freed 5553(6MB) AllocSpace objects, 510(9MB) LOS objects, 15% free, 21MB/25MB, paused 1.528ms total 113.323ms
    I/art: Background partial concurrent mark sweep GC freed 5754(6MB) AllocSpace objects, 528(10MB) LOS objects, 15% free, 21MB/25MB, paused 1.667ms total 120.876ms
    I/art: Background partial concurrent mark sweep GC freed 5743(6MB) AllocSpace objects, 513(10MB) LOS objects, 15% free, 21MB/25MB, paused 1.599ms total 115.166ms
    I/art: Background partial concurrent mark sweep GC freed 5604(6MB) AllocSpace objects, 507(9MB) LOS objects, 15% free, 21MB/25MB, paused 1.540ms total 117.786ms
    I/art: Background partial concurrent mark sweep GC freed 5895(6MB) AllocSpace objects, 554(10MB) LOS objects, 15% free, 22MB/26MB, paused 1.582ms total 126.550ms
    I/art: Background partial concurrent mark sweep GC freed 5961(6MB) AllocSpace objects, 538(10MB) LOS objects, 15% free, 22MB/26MB, paused 1.556ms total 123.707ms
    I/art: Background partial concurrent mark sweep GC freed 5969(6MB) AllocSpace objects, 548(10MB) LOS objects, 14% free, 23MB/27MB, paused 1.623ms total 129.052ms
    I/art: Background partial concurrent mark sweep GC freed 6311(7MB) AllocSpace objects, 580(11MB) LOS objects, 14% free, 23MB/27MB, paused 1.749ms total 137.854ms
    I/art: Background partial concurrent mark sweep GC freed 6355(7MB) AllocSpace objects, 580(11MB) LOS objects, 14% free, 23MB/27MB, paused 1.641ms total 137.932ms
    I/art: Background partial concurrent mark sweep GC freed 6112(6MB) AllocSpace objects, 545(10MB) LOS objects, 14% free, 23MB/27MB, paused 1.628ms total 145.860ms
    I/art: Background partial concurrent mark sweep GC freed 6586(7MB) AllocSpace objects, 628(12MB) LOS objects, 14% free, 24MB/28MB, paused 1.812ms total 152.395ms
    I/art: Background partial concurrent mark sweep GC freed 6180(6MB) AllocSpace objects, 527(10MB) LOS objects, 14% free, 24MB/28MB, paused 1.636ms total 145.680ms
    I/art: Background partial concurrent mark sweep GC freed 6424(7MB) AllocSpace objects, 613(11MB) LOS objects, 13% free, 24MB/28MB, paused 1.868ms total 147.552ms
    I/art: Background partial concurrent mark sweep GC freed 6973(7MB) AllocSpace objects, 651(12MB) LOS objects, 13% free, 25MB/29MB, paused 1.758ms total 155.076ms
    I/art: Background partial concurrent mark sweep GC freed 7246(8MB) AllocSpace objects, 671(13MB) LOS objects, 13% free, 25MB/29MB, paused 1.802ms total 158.771ms
    I/art: Background partial concurrent mark sweep GC freed 7619(8MB) AllocSpace objects, 717(14MB) LOS objects, 13% free, 26MB/30MB, paused 1.959ms total 172.607ms
    I/art: Background partial concurrent mark sweep GC freed 7883(8MB) AllocSpace objects, 729(14MB) LOS objects, 13% free, 26MB/30MB, paused 1.952ms total 175.818ms
    I/art: Background partial concurrent mark sweep GC freed 7770(8MB) AllocSpace objects, 716(13MB) LOS objects, 12% free, 26MB/30MB, paused 1.872ms total 175.913ms
    I/art: Background partial concurrent mark sweep GC freed 7695(8MB) AllocSpace objects, 702(13MB) LOS objects, 12% free, 26MB/30MB, paused 1.876ms total 170.383ms
    I/art: Background partial concurrent mark sweep GC freed 7916(9MB) AllocSpace objects, 745(14MB) LOS objects, 12% free, 27MB/31MB, paused 1.989ms total 182.644ms
    I/art: Background partial concurrent mark sweep GC freed 8126(9MB) AllocSpace objects, 757(14MB) LOS objects, 12% free, 27MB/31MB, paused 2.055ms total 184.057ms
    I/System: FinalizerDaemon: finalize objects = 35788
    I/art: Background partial concurrent mark sweep GC freed 8390(9MB) AllocSpace objects, 794(15MB) LOS objects, 12% free, 29MB/33MB, paused 1.997ms total 205.145ms
    I/art: Background partial concurrent mark sweep GC freed 8279(9MB) AllocSpace objects, 743(14MB) LOS objects, 12% free, 28MB/32MB, paused 1.977ms total 185.077ms
    I/art: Background partial concurrent mark sweep GC freed 8210(9MB) AllocSpace objects, 766(14MB) LOS objects, 12% free, 28MB/32MB, paused 1.910ms total 188.075ms
    I/art: Background partial concurrent mark sweep GC freed 8889(10MB) AllocSpace objects, 861(16MB) LOS objects, 11% free, 29MB/33MB, paused 2.130ms total 214.342ms
    Something like this
    It may be because I did left some reference to
    Context
    in some methods of
    ChessEngineUtils.
    As I needed to access
    context.PackageManager
    and I felt like it would not change anything to remove
    context
    parameter in such case.
    Could someone point me on a clear Coroutine guidance with/without Jetpack Compose ? I think this is the heart of my issue.
    This is my worker code, where I try to use coroutines. I have a main process with runs undefinitely, and a coroutine for reading process input, and another for reading process output.
    This is much better : I don't get all those GC. What I did is simply avoid creating process and coroutine in the infinite loop.
    This version is far way better : I was blocking the main loop with call to
    BufferedReader#readLine()
    . A simple check with
    BufferedReader#isReady()
    solved it.