79479105

Date: 2025-03-02 12:48:20
Score: 0.5
Natty:
Report link

This is a very interesting question (and thanks to @jmrk for in-depth answer), but I wanted to add something from a practical standpoint, as recently it bit me with Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory due to passing quite large object as a function argument using 2nd method (inside an object of params), and the only thing that saved me from heap out of memory was switching to the first method.

Detailed example, consider same function called in two ways (similar to the original question):

[...]
const veryLargeDataObject = {...}

// option 1
for (const step of steps) {
 process({ param1, param2, ...config}, veryLargeDataObject) // veryLargeDataObject is a separate param
}

// option 2
for (const step of steps) {
 process({ param1, param2, ...config, veryLargeDataObject}) // veryLargeDataObject is inside object with all other params
}

So, while in theory (if I understood docs and @jmrk's answer correctly), both calls should not create any veryLargeDataObject clones and GC would handle this just fine. In reality however, option 2 consistently lead to heap out of memory crash as soon as the for...of loop was called enough times to fill all allocated memory (~20 loops in my case). Switching to option 1 completely fixed the situation and speed up the loop significantly.

Hopefully it helps someone who encounters heap overflow due to unintentional object cloning.

Reasons:
  • Blacklisted phrase (0.5): thanks
  • Long answer (-1):
  • Has code block (-0.5):
  • User mentioned (1): @jmrk
  • User mentioned (0): @jmrk's
  • Low reputation (0.5):
Posted by: Kirill Kay