Unexpected Out Of Memory Error

Error: Out Of Memory Error
Details: Failed loading application

Today I was really frustrated by Garmin SDK

I have defined global Dictionary variable below and after that I was not able to even load application to emulator because of OutOfMemory error. 

    var wayPointsCoordinatesDictionary = {
        "1000" => [42.243712, -83.614653],
        "1001" => [42.241023, -83.612350],
        "1002" => [42.241013, -83.608362],
        "1004" => [42.241053, -83.602525],
        ...
        1100 records in total
        }

Out Of  Memory happens even if I reduce dictionary to 75 records.

Trivial math gives me size of Dictionary of about 1K for 75 records. So this size of dictionary is really critical for application? I cant believe!

I am a newbie with Garmin SDK, so could you please point me out to additional reading related to CIQ applications memory mapping, memory restrictions, etc?

P.S. My manifest requests for only two permissions

        <iq:permissions>
            <iq:uses-permission id="Communications"/>
            <iq:uses-permission id="Positioning"/>
        </iq:permissions>

  • Yeah, dictionaries are very expensive. In this case, not only do you incur the memory penalty for the run-time size of the dictionary as an object), you also incur a memory penalty for the code itself which constructs the dictionary.

    If you are able to limit your supported devices to CIQ 2.0 and above, try loading your data as a JSON resource:

    https://developer.garmin.com/connect-iq/core-topics/resources/#jsondata

    That way you save the memory for the code which would normally construct the dictionary, and the object itself doesn't have to be in memory all the time.

    Otherwise, try wrapping wayPointsCoordinatesDictionary in a function (e.g. getWayPointsCoordinatesDictionary()) so that the object doesn't have to be in memory all the time. This may not help depending on exactly when you need the dictionary to be available, though.

    If you want to see the true memory impact of your dictionary (for both the code and the object), try compiling the app for a device that has lots of available RAM, like the fenix6pro (1310720 bytes available for device apps.)

  • Something else you can try would be to flatten the dictionary into a linear array.

    e.g. If each waypoint can be transformed to an array index with simple math, then you can drop the keys completely and just have a flat array of coordinates.

    Or maybe that isn't possible -- then you could try having a dictionary which maps each waypoint to an index into the flat array of coordinates.

    Each array has about 8 bytes of overhead (iirc), so you're incurring a huge penalty by having 75 or 1000 arrays.

  • In the sim, you can get a good idea of what's going on with File>View Memory.  The big thing to keep an eye on is "peak memory".  When you look at the bottom line in the sim, what you see there is the idle memory and peak can go much higher.  You can expand the view and dig down into various things.

    The amount of memory available varies by app type as well as device, so that's something else to watch.

  • If you are able to limit your supported devices to CIQ 2.0 and above, try loading your data as a JSON resource:

    Thank you for suggestion. That trick works)

  • In the sim, you can get a good idea of what's going on with File>View Memory.  The big thing to keep an eye on is "peak memory".

    Now I understand that "peak memory" is a very critical reading for such low memory device. Thanks

  • If you use app settings, you'll also see a spike in peak memory if you change things while your app is running.

    When writing an app, I start thinking memory from my first line of code, as that's easier than going back and trying to find something when you're already at or near the max.

  • Thank you for letting me know.

    I feel that app settings is a next challenge for me)

    The people usually calls Android development "Embedded development". There it has Gigabytes of RAM, about 100MB limit per application, and almost  endless disk storage space 

    But it looks like these people should dive into Garmin SDK development in order to feel real Embedded development ))))