JavaScript memory usage benchmark
ID: javascript-memory-usage-benchmark
In this section we will use the file nodejs/bench_mem.js, tests are run on Node.js v16.14.2 from NVM, Ubuntu 21.10, on Lenovo ThinkPad P51 (2017) which has 32 GB RAM.
Related answer: stackoverflow.com/questions/12023359/what-do-the-return-values-of-node-js-process-memoryusage-stand-for/72043884#72043884
First using
topp from stackoverflow.com/questions/1221555/retrieve-cpu-usage-and-memory-usage-of-a-single-process-on-linux/40576129#40576129 let's observe the memory usage of some baseline cases.For a Node.js infinite loop nodejs/infinite_loop.jsThis gives approximately:
topp infinite_loop.js- RSS: 20 MB
- VSZ: 230 MB
Adding a single hello world to it as in nodejs/infinite_hello.js and running:leads to:We understand that Node.js preallocates VSZ wildly. No big deal, but it does mean that VSZ is a useless measure for Node.js.
topp infinite_hello.js- RSS: 26 MB
- VSZ: 580 MB
Forcing garbage collection as in nodejs/infinite_hello.js brings it down to 20 MB however:
topp node --expose-gc infinite_hello_gc.jsFinally let's see a baseline for which gives initially:but after a few seconds randomly jumps to:so we understand that
process.memoryUsage nodejs/infinite_memoryusage.js:node --expose-gc infinite_memoryusage.js{
rss: 23851008,
heapTotal: 6987776,
heapUsed: 3674696,
external: 285296,
arrayBuffers: 10422
}{
rss: 26005504,
heapTotal: 9084928,
heapUsed: 3761240,
external: 285296,
arrayBuffers: 10422
}First a baseline case with an array of length 1:This gives the same results as with:
node --expose-gc bench_mem.js n 1node --expose-gc infinite_memoryusage.js. The same result is obtained by doing:a = undefinednode --expose-gc bench_mem.js deallocIf we use we see that the memory is now, unsurprisingly, accounted for under Results for different N:We see therefore that typed arrays are much closer to what they advertise (4 bytes per element), even for smaller element counts, as expected.
Int32Array typed array buffers instead of a simple Array:node --expose-gc bench_mem.js array-buffer n NarrayBuffers, e.g. for N 1 million:{
rss: 31776768,
heapTotal: 6463488,
heapUsed: 3674520,
external: 4285296,
arrayBuffers: 4010422
}|| N
|| `arrayBuffers`
|| `rss`
|| `rss` per elem
| 1 M
| 4 MB
| 31 MB
| 5
| 10 M
| 40 MB
| 67 MB
| 4.6
| 100 M
| 40 MB
| 427 MB
| 4Now let's try one million objects of type gives:Disaster! Memory usage is up to 70 MB! Why?? We were expecting only about 24, 4 baseline + 2 * 10 for each million int?!
{ a: 1, b: -1 }:node --expose-gc bench_mem.js obj{
rss: 138969088,
heapTotal: 105246720,
heapUsed: 70103896,
external: 285296,
arrayBuffers: 10422
}And now an equivalent version using gives the same result.
class:node --expose-gc bench_mem.js classLet's try Array:is even worse at 78 MB!! OMG why.
node --expose-gc bench_mem.js arr{
rss: 164597760,
heapTotal: 129363968,
heapUsed: 78117008,
external: 285296,
arrayBuffers: 10422
} New to topics? Read the docs here!