Array data size limit?

Hello guys!

I have two dimensional array with fixed size (15x100). Empty slots are filled in order with strings containing 16-17 chars. In same stage when storing values the app crashes. So far I have not been able to reproduce this in simulator. 

i’m just wondering what is the data size limit of an array? Might that be the issue? 

is there any way to debug in watch?

Thanks!

  • I don't think there is a size limit, but the memory is limited. When you write or read from the storage then sometimes it crashes with a strange, unrelated error message (or without any) and this can happen even when you save much smaller data. It depends on the free memory at the time of the call. So the same data might be successfully saved if your code is smaller or your (other) data in the memory is smaller. You might be able to free up some memory by refactoring your code. I also recommend testing it on the device with the smallest amount of memory. It usually happens also in the simulator, though there might be some small differences (a few hundred bytes).

    Probably the best way to prevent the crash is to try to work with smaller data chunks.

  • There's no inherent size limit to arrays in Monkey C, but your app will crash if it runs out of memory. If this is truly the reason for the crash, you should be able to easily recreate this in the simulator.

    Is it possible to flatten your arrays? I understand that you seem to have 15 arrays of size 100, but could you use 1 array of size 1500 instead? There's a bit of overhead for each array (15 bytes), so this will save you a small amount of memory (15 * 15 - 1 * 15 = 210 bytes)

    However, the amount of memory consumed by (up to?) 1500 strings of 16-17 chars is pretty big (compared to the typical amount of memory available to CIQ apps). The amount of overhead for each string is 9 bytes, so 1500 strings of 17 chars will consume 1500 * 26 = 39,000 bytes. (This is more than the available memory for a CIQ data field on some devices.)

    That doesn't even take into account the overhead for arrays.

    15 arrays of 100 17-char strings = 15 * (15 + 100 * 26) = 39,225

    If you flatten your arrays the situation isn't much better:

    15 + 1500 * 26 = 39,015

    So in this particular situation, flattening the arrays into a single array probably won't help. (Unless you actually have 100 arrays of size 15, in which case you save 99 * 15 bytes of overhead which might not be insignificant.)

    If you're not able to recreate the exact conditions of the app crash in the simulator, you could always write some test code which fills up the array, if it already isn't full by default or in a typical run. If it is, and it's not crashing in the sim, that would kind of be a mystery to me. If it isn't, then your test code should case the app to crash in the sim at some point (and you can pinpoint how full the arrays are when the app crashes by logging your allocations with System.println()).

    What type of app is it and which device is it crashing on?

    What's the the typical (*) / max memory usage (according to the simulator)?

    (* By "typical", I mean the memory usage when you run the app, it finishes initializing and it's just doing whatever it typically does.)

  • Thanks a lot guys!!

    I think I need to rewrite this section then. The application is medicine tracker, I use one array to store the timestamps (as string) when medicines logged. Up to 15 medicines, up to 100 days of history. Perhaps I should split it by medicine and store instantly to storage.


    Testing in simulator is quite difficult as time simulation does not seem to work with apps. But as you FlowState suggested, writing some test code could solve that! Didn’t even think of that. The device it crashes on is Epix2 pro.

  • What is the crash you see on the device and where?  Two different ones come to mind.

    -out of memory

    -the watchdog

    when you do an add() to an array, a new array is created that's one element longer, the contents of the old array is copied to the new array, and then the old array is freed,  So the array takes about twice the normal space during that time, which can cause out of memory

    Depending on what you do with the array, you could be executing too many bytecodes without returning to the VM, which could trigger the watchdog

  • I use one array to store the timestamps (as string) when medicines logged

    Can you store each timestamp as an integer (Number) instead? Seems like it would be a lot more efficient. Then each timestamp would be 5 bytes (4 bytes for the int itself + 1 byte for data type), instead of 26 bytes.

    That's already 80% savings without considering any other changes.

  • Hmm.. I do not know how to identify the crash. Basically that happens when adding string to empty array slot. ConnectIQ logo pops up and app crashes.

  • Thanks for the tip, I guess I could do that!

  • https://developer.garmin.com/connect-iq/core-topics/debugging/

    App Crashes

    App crashes typically result in an app quitting unexpectedly or displaying an ‘IQ!’ icon, but does not cause the entire device to crash or reboot. This kind of crash is most commonly due to a bug in an app, though it can also be due to a bug in Connect IQ itself. Whenever an app crash occurs, a CIQ_LOG.YAML file is written or updated to /GARMIN/APPS/LOGS on the device, and contains information related to the crash that app developers may use to address the problem

    Also, if your app is on the store, the device will send crash reports to Garmin, and you can view them using the ERA Viewer (available via the command palette in VS Code). Only crash reports for the latest version of your app will be available this way.

    It's probably not worth it in this case, but you can always upload an app to the store as a beta, which means it's instantly approved and nobody but you can download it. (The most common use case for betas is to test app settings [*], which only work when the app is in the store.)

    [*] the kind of app settings that are defined in resource files and that you modify in the Connect IQ phone app, not on-device app settings.

  • Thanks!  "Unhandled Exception" was the error logged.  

  • If it was installed from the app store, you should see the crash log with ERA,

    You can also look on the device under garmin/apps/logs and the CIQ_LOG files. (the .bak is what's been synced.  the .yml is what's not synced).