LOW_MEMORY error when loading app

Posted on
  • Hello there!

    When I upload my code from the Web IDE to the watch, it runs as expected.
    https://www.espruino.com/ide/?gist=9df129529bccc133f9f82bf7b39de48f&upload
    (shows you current time and start message, until you press button 2 which stops everything)

    I am trying now to store it as an app.
    The code string is big (18 156 chars), so it is split in chunks and writes gracefully in file.
    https://www.espruino.com/ide/?gist=3fddc28e3188fd5f5cded6aa1d037cb0&upload

    But when I launch the app from the app launcher, I get:

    Execution Interrupted during event processing.
    New interpreter error: LOW_MEMORY,MEMORY

    Any hints on how I could troubleshoot this?

    I have LOW_MEMORY issues when reading my app from storage.
    The app is quite big: the code string is 18 156 characters long.

  • The issue you're hitting is that when you upload via the IDE, the code is executed/interpreted as it is uploaded - the actual JS text never exists in Bangle.js's RAM in one big block.

    When you save to a file, Espruino has to load that whole file into RAM and execute from there.

    So if you have to split the file up to save it, you may well hit issues trying to load/execute it too :(

    You've got two main options I guess:

    • Split your app into multiple files - have one main one that loads, and then 'eval' extra files from Storage. Even better if you can do it as/when they're needed.
    • Minify your code and upload the minified version to a file. At some point the IDE will be modified to do it all for you, but right now it's a little more tricky (but a lot easier than what you had to do to upload the code!)

    I'm planning on adding the ability to execute JS code directly from external storage which would basically solve all your issues, but that's going to need a bunch of testing before I can put it live.

  • Does having the application in modules (and storing them as functions) help?... because I just ran into same issues.

  • Hey folks!
    Thanks for the quick answers.

    few takeaways:

    1. splitting my app in chunks when writing it in storage is not a good idea: if it can not be saved in the first place, it means it won't fit in RAM when read

    2. as I have my own pipeline to bundle and minify my app, I will disable IDE minification in the future. This way it will be easier to get consistent results between stored app & REPL app.

    3. I've reached my limit as a web developer: the way I approached my app, with beautiful and reusable classes, icons as images, and intensive event usage, does not work in such constrained environment. I'll be more pragmatic now

    @allObjects my source code is split in different modules, and I use rollup & babel to transpile and bundle them in one file. Is there a way to split the app on the Bangle itself, using different "files" in storage?

  • Is there a way to split the app on the Bangle itself, using different "files" in storage?

    Yes - this might help :) http://www.espruino.com/Modules#from-storage

    Depending on the images, they may be eating up a bunch of space. You can store those in storage and load them as needed. A bit like is done for https://github.com/espruino/BangleApps/tree/master/apps/animals

    as I have my own pipeline to bundle and minify my app

    I'm not sure IDE minification will have much effect then. The code you uploaded definitely looked like minification could help it significantly though.

    splitting my app in chunks when writing it in storage is not a good idea

    ... for now :) At some point I think I will have to add the ability to execute code from Storage, so when that happens it'll be fine.

    I'll also be extending the IDE and command-line tools to do the chunking automatically though, so that should help you out

    1. 've reached my limit as a web developer: the way I approached my app, with beautiful and reusable classes, icons as images, and intensive event usage, does not work in such constrained environment. I'll be more pragmatic now

    Yep... everyone goes thru that transformation w/ or for tech / physical imlementation... architecturally / logically though one can still stay on the high road.

    I 'grew up' w/ 16..19 k for app, data and even system utils, such as ISAM / keyed access of records... that makes you focus a lot and forces you to choose your memory battles.

  • I've manage it with a better minification (thank you "terser's mangle" option!).

    One thing I'd like to confirm.
    With IDE minification disable, when I load my code straight to the bangle, process.memory().free returns 1023 when the app starts.
    When I store the exact same code on the bangle storage, and start the app with the launcher, the number of free blocks drops to 692.

    Is the difference due to the app launcher itself?
    Is there some memory I could reclaim?

  • Sat 2019.12.14

    What is the size of the app being run @feugy?

    Having the value free before upload and the difference in both cases would help here.

  • Hi Robin.

    I've update the links above:
    https://www.espruino.com/ide/?gist=9df12­9529bccc133f9f82bf7b39de48f&upload
    will write the minified app (8485 characters) straight to your bangle and run it.
    The very first instruction displays number of free blocks.

    Here is an example of a run (press button 2 to start, button 1 to pause, then button 3 to stop and reset):

    >> initial 694
    1053
    1053
    1053
    1053
    1053
    1050
    1050
    1050
    1050
    1050
    1050
    902
    932
    

    Now, the same code, but saved in Storage under "activities" name:
    https://www.espruino.com/ide/?gist=3fddc­28e3188fd5f5cded6aa1d037cb0&upload

    Long press Btn 3 to get the clock, then goes to settings, select "activities" and start/pause/stop

    > initial 496
    699
    699
    699
    699
    699
    696
    696
    696
    696
    696
    696
    696
    696
    546
    
  • Are you using an up to date bootloader and settings app from https://banglejs.com/apps/ ?

    Also, if you do process.memory() in the 'main scope' of the code you upload, it'll be run while the String of text that contains all the JS code is still in memory.

    There were some issues with the old one (like leaving clock source code around). There's actually an issue tracking this at https://github.com/espruino/BangleApps/issues/65 - I may modify things soon to really make sure everything is torn down before an app gets run.

  • You where right @Gordon.
    After I've updated the boot loader, the numbers are closer.

    Running the code:

    > initial 694
    1053
    1053
    1053
    903
    905
    916
    

    Running as an App

    > initial 771
    974
    974
    824
    856
    856
    
  • Hi - please can you try updating the Bangle.js interpreter firmware to the latest version from http://www.espruino.com/binaries/travis/master/?

    This morning I pushed some changes which execute code directly from the external flash memory by default. It means that any function that you have defined in a file that's in flash memory will have its code executed directly from flash without using up RAM. It will hopefully help you significantly

  • w00t :)
    Is this Bangle only, or should work for all other Espruinos?

    Reading your other comment, is this for strings stored in external flash? Or is this for general javascript execution / module loading?

  • It's Bangle only, because that's the only one where Storage isn't in flash memory that is memory mapped.

    Code executed from Storage on other platforms has always just referenced the memory rather than copy it to RAM first

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

LOW_MEMORY error when loading app

Posted by Avatar for feugy @feugy

Actions