Preserving memory in Monkey C


As for couple of last days I was fighting hard to preserve every single byte of memory, balancing just at the edge... maybe others will find that usefull - and even more - maybe Garmin will work on that to improve as well?

1. Do not use SWITCH / CASE construction. Instead - use IF / ELSE IF construction. It preserves memory, maybe not a lot, but always few bytes or more.

2. This is ridiculous? Do not use CONST variables. It looks like using directly values preserves memory. Don?t like it, but no choice there

3. It is beneficial to create a function whenever 2 or 3 lines of code are repeated. Just use params if required. It will save space

4. Avoid use of dictionaries!

5. For memory consuming operation try to assign to every non used variable NULL ? this will free memory

I'd appreciate - as the whole community - if others would share their findings too!
  • The status line is the sim is the idle memory.  In the sim, under file, there is "view memory", where you can see a whole lot more info.

  • guys, i'm in trouble:

    working on a watchface with json data. request was working ok, but suddenly i keep getting error -403 which means no enough mem.

    i blv the problem arouse due to my code growth. if i restrain # of samples the request procs ok. i dont want to split the requests now coz since the full samples requests was working until short before, i cant help but think that make it work again would be better than splitting the request. but now i am on a loop of reading all this thread and applying all i figure out as applicable to my code, changing tons of stuff, making the code worse (in some mentioned aspects), but not reclaimimng enough memory.

    i decided to post here so maybe someone has direct tips regarding http requests. imma keep searching but for now:

    -can someone teach me on how to check exactly which memory i need to free so request procs ok again and how i verify its size?

    -the response is the biggest data i am handling, storing it as a dictionary on a property. i believe that is my achilles'. do you guys think parsing the dictionary into something smaller would help or its size stored as property would not bother?

  • I think you mean -403 and not 403.  Understand that the memory available for the background is as low as 32k (28k actually), and that can impacted by things like global variables and what you have in your AppBase class, as that's loaded when the background runs.

    You can use System.getSystemStats().availableMemory to see what's going on in your background.

  • so, i did put this RIGHT BEFORE makeWebRequest:

            var myStats = System.getSystemStats();
            System.println("free: "+myStats.freeMemory);
            System.println("used: "+myStats.usedMemory);
            System.println("total: "+myStats.totalMemory);
    and got:

    Background: free: 26376
    Background: used: 35040
    Background: total: 61416

    wondering if these ~35k is what should not have exceeded 28k.

  • Different watches have different amounts of mem for the background, with the hin being 32k/28k.

    How large is the response you're getting?  Not just bytes, as the JSON data gets converted into a dictionary, and the more complex the data, the bigger the dictionary.  And while this conversion is going on you could use double the amount of memory (it needs the JSON data and the dictionary at that time.

    With the background using 35040, you won't be able to run on devices with the smaller memory for the background - that's for sure.

  • As a quick test, I put your code in one of my background services and used a fr245 as a target. (32k/28k max)

    Here's what I see

    -before makeWebRequest:

    Background: free: 17240
    Background: used: 11408
    Background: total: 28648

    -after getting data back


    Background: free2: 15240
    Background: used2: 13408
    Background: total2: 28648

    The first place I'd be looking is in your background itself, as 34k before the request limits what you can run on, and the background should be as lean as possible. You can see that the response is using about 2k

  • good idea! gonna decrease number of samples down to something runnable and do the same.

    -EDIT-

    So, i realized that before i make the request i was retrieving the huge dict via App.getProperty(). That was the main problem.

    Now i disabled the retrieving for testing and the request worked full length:


    Background: BEFORE request
    Background: free: 51264
    Background: used: 10152
    Background: total: 61416

    Background: Response code -> 200

    Background: AFTER response
    Background: free: 27808
    Background: used: 33608
    Background: total: 61416

    What i must do now is process the response dict into a smaller structure before storing. that probably will drastically reduce memory usage and allow the full request keeps rolling.

    If that prove to not be enough, next step must be splitting the requests.

    guess thats it for now.

    Thanks for the guidance.

  • With a "used" of 33608, that still means you can't run on a number of devices. Is the response really 23k or are you doing something where you have copies of different parts??

  • yeah the answer is that huge. today i make 1 request x 24 hours x 5 datapoints, which gives me 120 datapoints at once. of course i can split it into 24 requests x 1 hour x 5 datapoints which would reduce the load per request to only 5.

    focus now is learn how use and rotate images (and any guidance on this is welcome).
    later when everything get up and running on fr245m i plan on working the shrinks and cleanups.