5 Causes of Memory Leaks in Node.js and How to Fix Them

5 Causes of Memory Leaks in Node.js and How to Fix Them

Daily short news for you
  • 🤤🤤🤤

    » Read more
  • I don't know which coffee blog the references are from, but for the past few days, I've seen many people searching for coffee 🤔.

    They are looking for both brewing methods and types of beans, but unfortunately, they can't find any articles because I haven't written about those cases. Could it be fate? 😀🙏

    » Read more
  • Slightly startled this morning because Mac warned that Docker is malware.Type: "com.docker.socket" was not opened because it contains malware. This action did not harm your Mac"

    It seems this is an unintended issue and Docker has spoken up; if you still can't open the application, you might try the ways mentioned here: Incident Update: Docker Desktop for Mac

    » Read more

Problem

Memory leaks occur when an application fails to release memory that is no longer needed during its operation. Initially, the application may run smoothly, but over time, it becomes slower and can even crash, displaying a "JavaScript heap out of memory" message somewhere in the console.

By default, V8 in Node.js allocates 4GB for dynamic data, also known as Heap. This limit can be increased, but at the cost of decreased application performance. Reference data types like Object, Function, and Array are stored in the Heap. Therefore, if too many instances of these objects are allocated during the runtime of the application, it can lead to memory overflow.

If you already know the underlying causes of memory leaks, here are 5 common issues that can cause memory leaks until there is no more space left to leak.

5 Causes of Memory Leaks

Global Variables

Global variables are variables declared with var or this, or variables not declared with any keyword. When not declared with a keyword, they are assigned to the window object in the browser.

function variables() {
  this.a = "Variable one";
  var b = "Variable two";
  c = "Variable three";
}

These variables will not be released by the garbage collector of V8 until they are set to null. Make sure you control the variables you create when declaring them globally. It's even better to use use strict to have the compiler warn you every time you declare a global variable.

Be careful when using global variables to store Objects or Arrays. They will not be released until you set them to null, or they can accumulate data to the point of losing control, thus occupying a large portion of the Heap memory.

Breaking Down Large Data Processing into Chunks and Spawning

What happens when you try to retrieve several million records from a database into an object? Or when you read a million rows in an Excel file and process them through 77 more steps? I can assure you that you will likely encounter a "Heap out of memory" message before you can continue processing. When loading such large amounts of data, the Heap quickly becomes filled up, leaving no room to store new data. Not to mention, processing data on such a large object will slow down your application and cause other issues.

There are various ways to handle this situation, but a common approach is to break the data into smaller chunks for processing. Additionally, to speed up processing, you can create additional child processes in Node using worker threads, as mentioned in the article What are Worker threads? Have you used Worker threads in node.js before?.

Be Careful with setInterval

Be Careful with setInterval

setInterval is a function that allows us to repeatedly perform a task at regular intervals. It's fine as long as you control the number of setInterval functions. However, if you fail to control the excessive tasks that they carry, the allocated memory can quickly get out of control. Therefore, make sure to call clearTimeout when setInterval is no longer needed.

const arr = [];

const interval = setInterval(() => {
  arr.push(new Date());
}, 1000);

clearInterval(interval);

Remove Unused Variables from Closure

Although closures are often debated for whether they cause memory leaks or not, the fact that they still retain the values of variables even after the function has returned indicates that the Heap still has to bear the cost of this storage.

Here's an example of a closure function:

const fn = () => {
  let Person1 = { name: "2coffee", age: 19 };
  let Person2 = { name: "hoaitx", age: 20 };

  return () => Person2;
};

After calling and executing fn(), Person1 will be released, but Person2 will not because it is still referenced in the returned function.

Unsubscribe from Observers and Event Emitters

Observers and Event Emitters have similar issues as setInterval mentioned above. Keeping observers for a long time can cause memory leaks. Make sure to unsubscribe from observers whenever you no longer need them.

Example:

const EventEmitter = require("events").EventEmitter;
const emitter = new EventEmitter();

const bigObject = {};
const listener = () => {
  doSomethingWith(bigObject);
};

emitter.on("event1", listener);

bigObject will be retained until the listener is unsubscribed.

emitter.removeEventListener("event1", listener);

Even Node.js itself warns about memory leaks if there are more than 10 event listeners attached to an event emitter.

emitter.on("event1", listener);
emitter.on("event2", listener2);
...  
emitter.on("eventN", listenerN);

// will receive a warning similar to
// "(node) warning: possible EventEmitter memory leak detected. N listeners added. Use emitter.setMaxListeners() to increase limit."

Summary

Most memory leaks are difficult to detect until your application suddenly crashes. In such cases, your task is to identify and fix the underlying causes as soon as possible. Based on the 5 points mentioned above, I hope it will help you in resolving those issues.

If you discover any other cases that can cause memory leaks and ways to fix them, please comment below and share with everyone!

References:

Premium
Hello

Me & the desire to "play with words"

Have you tried writing? And then failed or not satisfied? At 2coffee.dev we have had a hard time with writing. Don't be discouraged, because now we have a way to help you. Click to become a member now!

Have you tried writing? And then failed or not satisfied? At 2coffee.dev we have had a hard time with writing. Don't be discouraged, because now we have a way to help you. Click to become a member now!

View all

Subscribe to receive new article notifications

or
* The summary newsletter is sent every 1-2 weeks, cancel anytime.

Comments (0)

Leave a comment...
Scroll or click to go to the next page