Out Of Memory Error “Failed loading application” before getGlanceView() on CIQ 3.4 devices

Hi,

when starting my app on a CIQ 3.4 device with 32 kB glance memory, such as the Fenix 6 Pro or Forerunner 945 LTE, I get an Out of Memory Error: Failed loading application.

The error occurs before the glance is started. AppBase.getGlanceView() has not been executed yet. The stack trace points to a seemingly random file that is not even part of the glance scope.

When I start the glance on a device with 64 kB glance memory, it only uses 13 kB of memory, with a peak usage of 15 kB. So this does not really seem to be caused by a lack of memory.

What else could cause such an error?

Here is the error message:

Error: Out Of Memory Error
Details: Failed loading application
Stack: 
  -  at D:\GitHub\ohg\source\main\data\communications\connection\RequestUiUpdateTask.mc:11 0x80000000 

Encountered app crash.

For reference, here is the code base, including the file the error points to:

https://github.com/openhab/openhab-garmin

  • Do you have a background services?  if so, you don't really have 32 kb for the glance, but 32kb for the background, glance, and globals combined.

  • Do you have a background services?  if so, you don't really have 32 kb for the glance, but 32kb for the background, glance, and globals combined.

    No, there is no background service.

    What exactly would fall under “globals” in this context?

    Here is my memory view when I start the glance successfully on other devices.

  • Globals are based on where you define things.

    import Toybox.Application;
    import Toybox.Lang;
    import Toybox.WatchUi;
    
    var globalVar="this is a global";
    function globalFun() {
      //this is a global function
    }
    
    // your appbase
    class MyAppBase extends Application.AppBase {
    ...
    }

    Also, after CIQ1, when you see a value of xxkb in the device configs, CIQ takes about 4kb of that, so you really don't have 32kb, you got about 28kb. 

    That's why in your screen shot and "Memory Usage", you see 59.9kb and not 64kb

  • Understand, thanks. I do not have any global variables or functions, and the number of classes in glance scope is also quite limited.

    I have now reduced the codebase a bit and can start the glance on the affected devices.

    Interestingly, the application data uses much more memory on CIQ 3.4 devices than on newer ones.

    My first suspicion was that bitmaps might be handled differently. I have quite a few of them, although none are in glance scope. Still, I tried removing the bitmaps, but the application data portion stays exactly the same in the glance on CIQ 3.4 devices.

    Apart from that, I only have a very small number of strings, properties, and settings.

    What else falls under “application data” that could account for the 16 kB I see on CIQ 3.4 devices?

    Here is the memory view on CIQ 3.4 devices after the codebase reduction:

    And here is the memory view for a CIQ 5.1 device, also after the codebase reduction:

  • What else falls under “application data” that could account for the 16 kB I see on CIQ 3.4 devices?

    Application data is any static data (i.e. initialized variables) compiled from your program source, in the same way that application code is any code compiled from your program source. 

    Static data such as large arrays (in Monkey C code, not resources) is handled differently in older (CIQ 3) devices vs CIQ 4+ devices.

    I found that for CIQ 3 (and older) devices, a huge amount of code is used just to initialize a static array. For example, to initialize a 100-element array in CIQ 3, the code for 100 sets of instructions to assign an element to an array is generated and stored in the PRG, as well the the data itself (each of the 100 elements).

    In contrast, for CIQ 4 and newer devices, there's no initialization in code, but everything is placed in the data section. 

    I realize this doesn't explain what you are seeing at all, but it does point to one significant difference between >=CIQ  4 and <=CIQ 3  that is somewhat related.

    Related thread/comment:  RE: Maximum .PRG file size error  

    Do you have static byte arrays? Just a guess. That's probably not it, otherwise I'd expect a huge difference in code for the CIQ 3 case, as well.

  • With devices that are ciq 4 or greater, things like bitmaps and loaded into the graphics pool and not the app's memory.

  • Do you have static byte arrays? Just a guess. That's probably not it, otherwise I'd expect a huge difference in code for the CIQ 3 case, as well.

    Thanks, I read the post you linked, and the findings are quite interesting.

    However, I do not have any static byte arrays. I do have some static constants defined within classes, not globally, including a few small arrays. Most of them are Booleans or Numerics, and including the array elements, this is probably around 50 values in total. Only a handful of those are available in glance scope.

    The glance in this app is really very simple: it reads a value from Storage and displays it in a TextArea.

    I have double-checked the classes annotated with :glance, and they are already reduced to the bare minimum. There are also no resources worth mentioning in glance scope. There are only about five settings/properties, and all other resources, such as bitmaps and strings, are not in glance scope.

    I still have a few ideas to reduce the codebase in glance scope slightly further, but that only works around the issue rather than solving it.

  • With devices that are ciq 4 or greater, things like bitmaps and loaded into the graphics pool and not the app's memory.

    The issue occurs already when the application is loaded, before any resources are loaded into memory.

    Also, the glance of this app does not use bitmaps, and there are no bitmap resources defined in glance scope.

  • Maybe this tool will help:

    https://github.com/pzl/ciqdb 

    CIQDB is the unofficial Connect IQ Debugger.

    It takes an already-compiled .prg or .iq file, make with the Connect IQ SDK, and parses it. It provides any symbols, debug sections, and more pulled from the binary.

    This will show you exactly what's in your data section. I've noticed that it fails on some PRGs with a slice out-of-bounds error though. For one toy app, it failed on the Fenix 8 build, but not the FR235 build.

  • Do you check the size of debug build? Try release. Before System 7, mapping of addresses to paths for displaying readable stack traces was included in data section.