Memory management in NodeJS

Table of Content

  • Understanding memory handling
  • Garbage Collector 
  • Javascript Memory Leak
  • How to check memory leak in Node.js

Understanding Memory handling

How nodejs organizes the memory?

Memory Management

Memory management is a way of assigning memory from your machine memory to your application and then releasing that memory back to your machine when no longer in use.

Application Memory Management

  • allocation
  • deallocation
  • garbage collection

Garbage Collector

  • Garbage collectors execute the process of finding memory which is no longer in use by the program and releasing it back to the OS for future reallocation.
  • Garbage collection is a way of managing application memory automatically.

Before

After

1. Reference count - Python, PHP
2. Mark and Sweep - Javascript

Garbage Collector Algorithms

All the objects initially have their marked bits set to false

Garbage Collector: Mark and Sweep

All Reachable objects have their marked bits changed to true.

Mark Phase

Non reachable objects are cleared from the memory.

Sweep Phase

Javascript Memory Leak

A Memory leak can be defined as a piece of memory that is no longer being used or required by an application but for some reason is not returned back to the OS and is still being occupied needlessly.

Common JavaScript Leaks

Accidental global variables

function foo() {
    bar = "this is a hidden global variable";
}
function foo() {
    this.variable = "potential accidental global";
}

foo();

undeclared variables: forgot to use var to declare it

a reference to an undeclared variable creates a new variable inside the global object

accidental global variable can be created is through this

To prevent these mistakes from happening,

add 'use strict'; at the beginning of your JavaScript files.

How to check Memory Leak in Node.js

Use process.memoryUsage

const arr = [1, 2, 3, 4, 5, 6, 9, 7, 8, 9, 10];
const used = process.memoryUsage();
console.log(`used: ${JSON.stringify(used)}`);
for (let key in used) {
  console.log(`${key} ${Math.round(used[key] / 1024 / 1024 * 100) / 100} MB`);
}

Output:

memory usage for small array

memory usage for big array

let arr = Array(1e6).fill("some string");
const used = process.memoryUsage();
for (let key in used) {
  console.log(`${key} ${Math.round(used[key] / 1024 / 1024 * 100) / 100} MB`);
}

Output:

Take snapshot in Chrome

Using heapdump npm package

Example of leak code

const express = require('express')
const app = express();
const port = 4000;
const leaks = [];
app.get('/bloatMyServer', (req, res) =>
{
   const redundantObj =
   {
     memory: "leaked",
     joke: "meta"
   };

  [...Array(10000)].map (i => leaks.push(redundantObj));   
  res.status(200).send({size: leaks.length})
});

app.listen(port, () => console.log(`Example app listening on port ${port}!`));

DEMO

Reference

Made with Slides.com