I was trying to recreate a FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory that I get in production on heroku.
But my local machine will readjust the heap limit.
If I set the heap size limit node --max-old-space-size=200 ./bin/www.js the limit seems to readjust as I near it. It goes from around 200mb to over 800mb. I would expect it to stay at 200mb and crash. Why does this happen?
Reproduced memory leak
const crashArray = [];
...
app.get('/leak', async (req, res, next) => {
v8Print('before push to array');
crashArray.push(...Array(0.12e6).fill('some string'));
crashArray.push(...Array(0.12e6).fill('some string'));
crashArray.push(...Array(0.12e6).fill('some string'));
crashArray.push(...Array(0.12e6).fill('some string'));
crashArray.push(...Array(0.12e6).fill('some string'));
crashArray.push(...Array(0.12e6).fill('some string'));
v8Print('after push to array');
res.sendStatus(200);
});
Log function
const v8 = require('v8');
// for memory allocation heap debugging
module.exports.v8Print = (message) => {
const heapStats = v8.getHeapStatistics();
const heapStatsMB = heapStats;
for (const key in heapStatsMB) {
heapStatsMB[key] = `${(((heapStatsMB[key] / 1024 / 1024) * 100) / 100).toFixed(2)} MB`;
}
console.log('');
console.log(message);
console.table(heapStatsMB);
console.log('');
};
I call the GET /leak request a bunch of times to reproduce a leak. When I get close the heap limit adjusts.
before push to array
┌─────────────────────────────┬─────────────┐
│ (index) │ Values │
├─────────────────────────────┼─────────────┤
│ total_heap_size │ '155.28 MB' │
│ total_heap_size_executable │ '0.80 MB' │
│ total_physical_size │ '154.35 MB' │
│ total_available_size │ '122.37 MB' │
│ used_heap_size │ '114.22 MB' │
│ heap_size_limit │ '248.00 MB' │
│ malloced_memory │ '0.01 MB' │
│ peak_malloced_memory │ '2.10 MB' │
│ does_zap_garbage │ '0.00 MB' │
│ number_of_native_contexts │ '0.00 MB' │
│ number_of_detached_contexts │ '0.00 MB' │
└─────────────────────────────┴─────────────┘
after push to array
┌─────────────────────────────┬─────────────┐
│ (index) │ Values │
├─────────────────────────────┼─────────────┤
│ total_heap_size │ '169.45 MB' │
│ total_heap_size_executable │ '0.80 MB' │
│ total_physical_size │ '168.53 MB' │
│ total_available_size │ '175.61 MB' │
│ used_heap_size │ '128.00 MB' │
│ heap_size_limit │ '848.00 MB' │ // <----- heap size limit changes
│ malloced_memory │ '0.01 MB' │
│ peak_malloced_memory │ '2.10 MB' │
│ does_zap_garbage │ '0.00 MB' │
│ number_of_native_contexts │ '0.00 MB' │
│ number_of_detached_contexts │ '0.00 MB' │
└─────────────────────────────┴─────────────┘