Why is memory consumption increases, than drops and stays constant

24 views Asked by At

I have the following simple program:

const fs = require("fs");
const time = Date.now();
const file = fs.createWriteStream('./test.txt');

let written = true;

file.on('drain', function () {
    written = true;
});

const interval = setInterval(function () {
    if (Date.now() - time > 10000) {
        clearInterval(interval);
    }

    if (written) {
        written = file.write(new Array(1000000).join('z'));
        console.log(Math.floor(process.memoryUsage().rss / (1024 * 1024)));
    }
}, 100);

And the following memory consumption is logged:

29 38 48 58 67 77 86 96 105 115 125 134 144 153 163 173 182 192 201 211 220 230 240 249 259 268 278 287 297 307 316 326 335 345 355 364 374 383 393 402 412 422 431 441 450 460 470 479 489 498 508 518 527 537 546 556 565 575 585 561

87 97 25 35 44 25 35 44 25 35 44 25 35 44 25 35 44 25 35 44 25 35 44 25 35 44 25 35 44

As you may see it was growing to 561 MB, but that dropped to 87 MB and then stayed under 100 MB. What happens here?

1

There are 1 answers

2
T.J. Crowder On BEST ANSWER

Your code is creating largely-empty temporary objects (new Array(1000000) just creates an empty array with length set to 1000000; it doesn't create an array with 1000000 entries) and then large temporary strings (and some housekeeping objects) every 100ms or so. At some point, it stops doing that (when you've set written to true).

After each iteration, the array and housekeeping objects will be eligible for garbage collection immediately, and the string once it's done being written to the file. But that doesn't mean they're cleaned up immediately.

Once the system stops doing that, eventually garbage collection kicks in and releases all of those objects and strings.

If the timer kept going, eventually you'd see GC even while it was running, but there's no significant memory pressure in your example so there was no reason to prioritize it.