Where in my code is the Peak Memory allocated?

Like so many others, I need to optimize my code. So, I have read up on a lot of very good discussions in this forum on how to optimize code. And, it is my understanding that it is the Peak Memory in the Active Memory display that I need to bring down so my App Field does not crash. To get started, I thought I better figure out where exactly in my code that I have the most memory allocated. Thinking that Peak Memory = my code + stack + allocated variables.

So, I inserted System.println(System.getSystemStats().usedMemory) calls to see where in my code I could find a match with Peak Memory. I could Indeed figure out where in my code I have most memory allocated, but the number was not as high as Peak Memory. Thinking that it was something about e.g. memory for Settings in my App, I made the following experiment to learn more about Peak Memory:

In Eclipse I created a new simple datafield. A very simple App! Also here nowhere in the code I allocate the Peak Memory. In fact, I can e.g. in compute() insert var arr = new[1024]b; without impacting Peak Memory. I need to allocate more than 1300 bytes before I see an increase in Peak Memory!?

So, my question is: where is the peak memory allocated? Howcome in the most of all simple Apps, I can allocate that much memory without any problem? How can I figure out what elements the Peak Memory is comprised of (besides the obvious like code, static allocations, etc) ?

Any insights here is much appreciated - I am new to this and would like to learn!

Thanks!
  • I've noticed in watchfaces I've created, that peak memory is higher after startup than used memory (without me deallocating anything) - so something must happen at startup in the system - reading default settings values maybe?

    And then peak usage for me tends to occur after sending new settings from Garmin Connect Mobile (i.e. while the watchface is actively running) - apparently the system temporarily allocates extra memory to hold both the old & new settings values while they are updated.

  • The memory usage you see on the bottom line of the simulator is the "idle" memory - your code isn't running, and peak is the peak since your app started.  Not quite what you expect, as the peak never drops, only increases while running.  And there are things that increase it that may not be directly in your code, with the prime example being changing app settings while your app is running.   This something that occures when an app runs fine until you change settings and then the app crashes.  Another one that may not be obvious is doing an add() to an array.  Memory is allocated for the new size, the old data is copied over, then the original memory is release, so for a breif time, an array is taking double the memory you'd expect.

    Your actually running memory usage is somewhere between idle and peak, so a change in your code might not be clear unless you increase peak, and that's hy you really didn't see anything with the new [1024]b, as it was still below peak when cumpute() runs. (it could be more memory was used in compute())

  • Thankyou for your reply!

    I see the point that peak, unlike, idle, will include memory usage in events like settings change, ressource loads, etc. Which is why I did the experiement with the very simple field sample that has none of all of that. It's as simple as it can possibly get. Yet, something make the peak memory much higher than anywhere in the very simple code. This is the part I don not understamd.

  • There's a lot that happens when an app starts up and things are initialized.  I suspect that's it

  • there's a lot of overhead you can't do anything about:

    - the startup sequence before you get to initialize gets the peak memory up 

    - when sending settings I believe there is 3 times the amount of settings space allocated (the old settings with it's values, the new settings that need to be applied and the new settings that will be written). Providing configuration to your app is expensive.

    The simulator may also not always be representative of how much the device will consume. It could be that you're within limits in the sim and get out of memory on the device or vice versa. If you can it's good to get a bit of a safety barrier memory wise.... (but this is especially hard if you write a data field that has to operate within a 16k space. I've written a few data fields where I have less than 0.1k left and just hoped for the best :) At the time I always thought that watch face designers had a real luxury with having 92k available, but after I wrote a watch face of my own and pretty much filled up the memory space too, I have changed my mind about this. The tight memory space is definitly a challenge :) ). 

  • Makes good sense! I have btw already given up on the 16k devices...

    With respect to 3 * settings Space cost, does the simulator try to take that into account when calucating the Peak Memory - or do I need myself to try to do worst case testing - e.g. using the longest strings I allow for settings? 

  • That is one of the things you want to test in the sim with the App Settings Editor.  Start you app running, look at peak, then use the settings editor and then look at peak.  Things can vary not only based on how big the values are for settings, but the number of settings (the complexity).  While 1 setting with a 100 char string should be ok, but things will be different with 100 settings, and a number for each.

  • Thankyou, I will make sure to do so!