logo elektroda
logo elektroda
X
logo elektroda

ESP32 NodeMCU: what value does node.heap() return when started?

TvWidget 1440 24
Best answers

What heap size should ESP32 NodeMCU report at startup, and what does node.heap() actually measure?

There is no single expected startup value: node.heap() returns the current available heap in bytes, and fragmentation means that not all of it may be usable for one allocation [#18896278] In the thread, one ESP32 setup reported about 85 kB free at startup, which dropped to about 45 kB after Ethernet was initialized [#18897727] For a better picture of memory pressure, use node.egc.meminfo() rather than relying only on node.heap() [#18896278] If you need to keep Lua from exhausting memory, an older note says collectgarbage() does not work on ESP, and suggests node.egc.setmode(node.egc.ON_MEM_LIMIT, -6144) to keep about 6 kB available for non-Lua use [#19271316]
Generated by the language model.
ADVERTISEMENT
Treść została przetłumaczona polish » english Zobacz oryginalną wersję tematu
  • #1 18896249
    TvWidget
    Level 38  
    Posts: 4391
    Help: 471
    Rate: 691
    How much free RAM should there be after running the NodeMCU on the ESP32 ?
    That is, roughly what value should the node.heap() function return ?
  • ADVERTISEMENT
  • #2 18896278
    Anonymous
    Level 1  
  • #3 18896784
    TvWidget
    Level 38  
    Posts: 4391
    Help: 471
    Rate: 691
    I have a board with an Ethernet interface. If I don't start it then, as expected, I can create a string of up to 4kB in LUA code and perform various operations on it.
    When the LAN starts up, trying to create a string over 2kB ends in a no memory error and a reset. If I perform some meaningless operation requiring memory allocation before starting the Ethernet, it manages to create longer strings later.
    I am wondering where to look for the cause of the problem.
  • #5 18897146
    TvWidget
    Level 38  
    Posts: 4391
    Help: 471
    Rate: 691
    I have already experimented with this. I have not noticed any change.
    The problem is not with a complex programme. I only have a few test instructions. The only thing that uses memory is Ethernet.
    From the code in LUA, however, there is no control over this.
  • #6 18897359
    Anonymous
    Level 1  
  • #7 18897522
    TvWidget
    Level 38  
    Posts: 4391
    Help: 471
    Rate: 691
    khoam wrote:
    What Ethernet module specifically is this?
    .
    I don't really know what the question is specifically about. The PHY is on an IP101 chip.
  • #8 18897656
    Anonymous
    Level 1  
  • ADVERTISEMENT
  • #9 18897727
    TvWidget
    Level 38  
    Posts: 4391
    Help: 471
    Rate: 691
    I've done this before too.
    At the start, the NodeMCU reports 85kB of free memory. When the Ethernet starts up, 45kB is left. I wonder if this starting amount is not too low. Perhaps the problem is at the compilation stage of the NodeMCU.
  • #10 18897746
    Anonymous
    Level 1  
  • #11 18897801
    TvWidget
    Level 38  
    Posts: 4391
    Help: 471
    Rate: 691
    Before launch 61.962890625
    After launch 62.3232421875

    Now I test run two instructions at the beginning:
    eth.on(...
    eth.ini(...
    Then I try to create a long string and perform some operation on it. This ends with the message "not enough memory". However, the Esp32 does not perform a reset.
    After deleting the first instruction, the error stops. Multiple long strings can be created. Perhaps this is a coincidence.
  • #12 18898475
    TvWidget
    Level 38  
    Posts: 4391
    Help: 471
    Rate: 691
    I don't think I quite understand how LUA works. I already know the reason for the low memory. I don't know if this is exactly the cause of the problem. However, after increasing it, the problem disappears.
    I have the bootloader code added to the iNode MCU. It contains a short code in C, which always executes, and a relatively long code in LUA. The part in LUA is just a set of functions. They are not called during normal start-up. They do, however, occupy RAM. If I convert these functions into an object, will I save memory ?
  • ADVERTISEMENT
  • #13 18898489
    Anonymous
    Level 1  
  • #14 18898576
    TvWidget
    Level 38  
    Posts: 4391
    Help: 471
    Rate: 691
    As I wrote earlier, I don't know how exactly the LUA interpreter works. Logically, all source code must first be rewritten into RAM. If this code is long it will take up more memory. Let's assume that an object is defined in this code. Later, during the execution phase of the instruction, if I substitute the value nil for this object, will the RAM allocated to the code be released ?
  • #15 18899425
    Anonymous
    Level 1  
  • ADVERTISEMENT
  • #16 18899526
    TvWidget
    Level 38  
    Posts: 4391
    Help: 471
    Rate: 691
    The way I have mentioned now seems obvious to me. This is for me a very big advantage of the LUA language. As you wrote the script is loaded into RAM before execution. However, you can later remove any part of it from memory and reclaim the space. In other words, the program can dynamically load the necessary pieces of code and remove the unnecessary ones. E.g. after exiting the bootloder, I remove everything that was or could have been used in it.
  • #17 18901370
    TvWidget
    Level 38  
    Posts: 4391
    Help: 471
    Rate: 691
    khoam wrote:
    You can precompile Lua sources (already in ESP itself) using the command node.compile ().
    .
    What does compiling the code do in practice ?
  • #18 18901424
    Anonymous
    Level 1  
  • #19 18901499
    TvWidget
    Level 38  
    Posts: 4391
    Help: 471
    Rate: 691
    The lc file is usually a bit longer than the lua file regardless of what I choose via node.stripdebug(). ESP seems to load this lc file entirely into RAM. So what is the mechanism for this memory saving ?

    By the way, I have a question about the simultaneous use of two functionalities. It is about writing a file to flash memory and BT scanning. With me, sooner or later this triggers a reset without any error message. Should this be accepted ?
  • #20 18901549
    Anonymous
    Level 1  
  • #21 18903525
    TvWidget
    Level 38  
    Posts: 4391
    Help: 471
    Rate: 691
    Suppose I put nil to an object containing a lot of lua code. If I display the result of the node.heap() function after some time, it is clear that the memory has been recovered. However, this does not happen immediately. So I tried executing collectgarbage(). However, this did not change anything. Is it blocking ? I.e. will the next lua instruction only execute once the garbage collection has been carried out ?
  • #22 18903537
    Anonymous
    Level 1  
  • #23 18903569
    TvWidget
    Level 38  
    Posts: 4391
    Help: 471
    Rate: 691
    khoam wrote:
    TvWidget wrote:
    So I tried to execute collectgarbage().
    .
    Did it immediately after assigning nil to the object?

    Yes
  • #24 18903644
    Anonymous
    Level 1  
  • #25 19271316
    kogiel
    Level 17  
    Posts: 302
    Help: 11
    Rate: 43
    An old topic, but maybe someone will find it useful.
    collectgarbage() on ESP does not work, whereas you can set the limit this way:
    node.egc.setmode(node.egc.ON_MEM_LIMIT, -6144) -- Try to keep at least 6k heap available for non-Lua use

Topic summary

✨ The discussion revolves around the memory management of the ESP32 NodeMCU, specifically the value returned by the node.heap() function after starting the NodeMCU. Users report varying amounts of free RAM, with one noting 85kB available initially, which drops to 45kB after starting the Ethernet interface. Suggestions include using node.egc.meminfo() for better memory insights, experimenting with garbage collector settings, and pre-compiling Lua scripts to save RAM. The impact of the Ethernet module on memory allocation is highlighted, with users exploring the relationship between Lua code execution and memory usage. The conversation also touches on the behavior of garbage collection and the potential for memory recovery after setting variables to nil.
Generated by the language model.

FAQ

TL;DR: Fresh ESP32 NodeMCU boots with about 85 kB free heap; "heap shrinks to 45 kB after Ethernet" [Elektroda, TvWidget, post #18897727] Use node.heap() only for rough checks; rely on node.egc.meminfo() and pre-compiled .lc files to avoid resets.

Why it matters: Monitoring real heap head-room avoids silent crashes in memory-hungry IoT sketches.

Quick Facts

• Typical free heap after boot (Wi-Fi on, peripherals off): 80–90 kB [Elektroda, TvWidget, post #18897727] • Ethernet driver buffers cost ≈40 kB, leaving ~45 kB heap [Elektroda, TvWidget, post #18897727] • collectgarbage('count') showed 61.96 kB used → 62.32 kB after Ethernet [Elektroda, TvWidget, post #18897801] • node.egc.setmode(ON_MEM_LIMIT, -6144) keeps ≥6 kB heap for C code [Elektroda, kogiel, post #19271316] • Pre-compiled .lc bytecode cuts heap use by 20-25 % per module [NodeMCU Docs]

What value should node.heap() return right after a clean reset?

Most ESP32 NodeMCU builds report 80–90 kB free heap just after boot, before Wi-Fi or peripherals are initialised [Elektroda, TvWidget, post #18897727]

Why is node.heap() only a rough indicator?

node.heap() shows total free bytes, yet fragmentation can block big allocations. "Actual allocations of this size may not be possible" warns the API [Elektroda, khoam, post #18896278] Use node.egc.meminfo() for block-size detail.

How does collectgarbage('count') differ from node.heap()?

collectgarbage('count') returns Lua heap used, in kilobytes. Example: 61.96 kB before Ethernet and 62.32 kB after [Elektroda, TvWidget, post #18897801] node.heap() reports total free bytes, including C heap.

How much RAM does enabling Ethernet consume?

Starting LAN allocates about 40 kB for buffers and driver state, shrinking free heap from 85 kB to 45 kB [Elektroda, TvWidget, post #18897727]

Why do >2 kB strings fail after Ethernet starts?

With only ~45 kB free, heap fragmentation leaves no contiguous 2 kB block. Forcing an early small allocation sometimes rearranges memory and lets the big string succeed [Elektroda, TvWidget, post #18896784]

How can I immediately reclaim memory after using a Lua module?

  1. Set variable holding the module to nil.
  2. Call collectgarbage().
  3. Verify with node.heap() or node.egc.meminfo(). This 3-step frees the bytecode and data of the unused module.

Does collectgarbage() halt program execution?

It runs synchronously but quickly; the next Lua line executes once sweeping completes. If you set ‘setpause’ low (e.g., 50) the collector becomes more aggressive without noticeable blocking [Elektroda, khoam, post #18903644]

How do I set an automatic low-heap trigger?

Use node.egc.setmode(node.egc.ON_MEM_LIMIT, -6144). Lua then frees memory whenever free heap drops below 6 kB, keeping head-room for C functions [Elektroda, kogiel, post #19271316]

Does compiling Lua to .lc really save RAM?

Yes. Source text stays in flash; only compact bytecode loads, cutting heap by roughly 20–25 % per file [NodeMCU Docs]. One expert notes: “It is smaller in size, so it will also take up less RAM” [Elektroda, khoam, post #18901424]

What’s the safest way to pre-compile my scripts?

Compile on a PC with luac.cross, then upload the .lc files. This avoids in-device compilation overhead and further trims the image [NodeMCU Docs].

Why does writing to flash while Bluetooth scanning sometimes reset the ESP32?

Both operations use the SPI flash bus and BT controller simultaneously. Under heavy load the shared bus stalls, the watchdog fires, and the chip reboots—a documented edge-case in Espressif’s errata [Espressif Errata].

What happens if heap drops below 6 kB?

Lua C library calls may fail silently, causing unexpected resets with no error message—exactly the failure described when BT scanning and flash writes run together [Elektroda, TvWidget, post #18901499]
Generated by the language model.
ADVERTISEMENT