JavaScript Memory Leak Examples and Solutions

Ramkumar Khubchandani
3 min readJan 3, 2025

--

  1. Forgotten Event Listeners
  • Problem: When you add event listeners but never remove them, they keep holding memory even if you don’t need them anymore
  • Solution: Always create a cleanup method to remove event listeners when you’re done with them
  • Real-world example: Think of it like subscribing to a magazine — if you move houses but don’t cancel your subscription, magazines keep coming to your old address
// ✅ Good Practice: Clean up event listeners
class BetterNewsletterWidget {
constructor() {
this.button = document.querySelector('#subscribe');
// Bind the method to keep reference
this.boundHandler = this.handleSubscribe.bind(this);
this.button.addEventListener('click', this.boundHandler);
}

handleSubscribe() {
// Handle subscription logic
}

// Clean up when done
destroy() {
this.button.removeEventListener('click', this.boundHandler);
}
}

2. Accidental Global Variables

  • Problem: When you forget to use ‘let’ or ‘const’, JavaScript creates global variables that stay in memory
  • Solution: Always declare variables properly with ‘let’ or ‘const’
  • Real-world example: It’s like leaving your belongings in a public space instead of your private room
function createUser() {
// ❌ Bad Practice: Missing 'let' or 'const' creates global variable
user = { name: 'John', age: 30 };
}

// ✅ Good Practice: Properly declare variables
function createUserBetter() {
const user = { name: 'John', age: 30 };
return user;
}

3. Circular References

  • Problem: When two objects refer to each other, creating a never-ending loop
  • Solution: Use WeakMap for storing references, which allows objects to be garbage collected
  • Real-world example: Like two friends each holding onto a rope — neither can let go unless someone cuts the rope
// ❌ Bad Practice: Objects referring to each other
let student = {
name: 'Alice'
};

let course = {
title: 'JavaScript'
};

// Creating circular reference
student.enrolledCourse = course;
course.enrolledStudent = student;

// ✅ Good Practice: Use WeakMap for references
const studentCourses = new WeakMap();

let betterStudent = {
name: 'Alice'
};

let betterCourse = {
title: 'JavaScript'
};

// Store reference in WeakMap instead
studentCourses.set(betterStudent, betterCourse);

5. Forgotten Intervals

  • Problem: Starting intervals (like timers) but never stopping them
  • Solution: Always store interval IDs and clear them when no longer needed
  • Real-world example: Like leaving your car running in the parking lot — it keeps using fuel until you turn it off
function betterCounter() {
let count = 0;
const intervalId = setInterval(() => {
console.log('Counting:', count++);
if (count > 10) {
clearInterval(intervalId);
}
}, 1000);
return intervalId;
}

5. Closures Holding References

  • Problem: Functions keeping references to large data even after it’s no longer needed
  • Solution: Explicitly clean up references when you’re done with them
  • Real-world example: Like keeping a huge photo album in your backpack even though you only need one picture
// ❌ Bad Practice: Closure holding reference to large data
function processData() {
const hugeData = new Array(1000000).fill('🐘');

return function() {
console.log('Data length:', hugeData.length);
};
}

// ✅ Good Practice: Clean up references when done
function betterProcessData() {
let hugeData = new Array(1000000).fill('🐘');

const result = function() {
console.log('Data length:', hugeData.length);
};

// Clean up reference
const cleanup = () => {
hugeData = null;
};

return { result, cleanup };
}

6. DOM References

  • Problem: Storing references to DOM elements that might be removed
  • Solution: Use WeakRef for DOM references so they can be garbage collected when elements are removed
  • Real-world example: Like keeping addresses of stores that have closed down
const elements = {
header: new WeakRef(document.querySelector('header')),
sidebar: new WeakRef(document.querySelector('sidebar'))
};

// Access elements safely
function getElement(key) {
const element = elements[key].deref();
return element ? element : null;
}

Do You want to learn more like above content ?

Follow me or message me on Linkedin.

--

--

Ramkumar Khubchandani
Ramkumar Khubchandani

Written by Ramkumar Khubchandani

Frontend Developer|Technical Content Writer|React|Angular|React-Native|Corporate Trainer|JavaScript|Trainer|Teacher| Mobile: 7709330265|ramkumarkhub@gmail.com

No responses yet