JavaScript Memory Leaks Demonstrations and Fixes

Pro Members Only

This lesson is available if you have an active subscription.

Alternatively, some member might be able to gift it to you.

If you already have a subscription, you can sign in.

Professional Modern JavaScript Lessons

1.Course Intro
free
⏱️ 1:13
2.Setup & Tooling
free
⏱️ 3:32
3.Debugger Statements and Breakpoints
free
⏱️ 2:17
4.Primitive Data Types and Values
free
⏱️ 3:06
5.JavaScript Variables - let and const
free
⏱️ 4:50
6.Comments in JavaScript
free
⏱️ 2:55
7.JavaScript Identifer Naming
free
⏱️ 2:52
8.Using TypeScript
free
⏱️ 4:26
9.JavaScript String Masterclass
free
⏱️ 9:29
10.JavaScript Boolean Type
⏱️ 6:45
11.Missing Guide to JavaScript Numbers
⏱️ 15:28
12.JavaScript Objects Demystified
⏱️ 13:33
13.Functions in JavaScript
⏱️ 20:25
14.JavaScript Arrays Masterclass
⏱️ 22:31
15.JavaScript If Else Statements and Best Practices
⏱️ 6:13
16.JavaScript Conditional Expressions
⏱️ 8:38
17.JavaScript Loose vs Strict Equality
⏱️ 4:02
18.Truthy vs Falsy in JavaScript
⏱️ 3:44
19.Concept of JavaScript Nullish and Unification
⏱️ 5:51
20.JavaScript Classes - Object Oriented Programming
⏱️ 10:30
21.JavaScript Error Handling and Exceptions
⏱️ 13:21
22.JavaScript Nullish Operators
⏱️ 5:48
23.JavaScript Switch Statement Masterclass
⏱️ 8:07
24.JavaScript For Loop Iteration Simplified
⏱️ 10:59
25.JSON Masterclass
⏱️ 7:59
26.JavaScript While and Do While Loops
⏱️ 2:52
27.JavaScript Date and Time Simplified
⏱️ 13:16
28.this in JavaScript
⏱️ 12:04
29.JavaScript Tagged Templates Masterclass
⏱️ 5:48
30.Promises in JavaScript
⏱️ 10:01
31.JavaScript Async Await Masterclass
⏱️ 9:00
32.JavaScript Symbols Demystified
⏱️ 7:25
33.JavaScript Iterators and Iterables
⏱️ 8:50
34.JavaScript Generators Simplified
⏱️ 9:17
35.JavaScript Prototype - The Secret Guide
⏱️ 11:21
36.JavaScript Set Builtin Data Structure
⏱️ 9:52
37.JavaScript Map Builtin - HashMap Magic
⏱️ 10:38
38.JavaScript Deferred Promise Pattern - withResolvers
⏱️ 3:35
39.Cloning and Deep Copying in JavaScript
⏱️ 3:14
40.JavaScript Async Await Sequencing and Execution Masterclass
⏱️ 10:31
41.JavaScript Memory Management Masterclass
⏱️ 5:26
42.JavaScript WeakMap Demystified
⏱️ 8:58
43.JavaScript bigint Masterclass
⏱️ 5:35
44.JavaScript WeakSet Explained with Examples
⏱️ 7:47
45.JavaScript Regular Expressions Masterclass
⏱️ 17:54
46.JavaScript Weak References Demystified
⏱️ 5:29
47.JavaScript Memory Leaks Demonstrations and Fixes
⏱️ 6:01
48.Semicolon Free Coding in JavaScript
⏱️ 3:46
49.JavaScript Modules Masterclass
⏱️ 11:36

JavaScript Memory Leaks Demonstrations and Fixes

Subscription Required

You must have an active subscription to access this content.
If you already have a subscription, you can sign in.

Variables Cause Memory Leaks

This will crash:

function allocate() {
const result = [];
for (let i = 0; i < 2500; i++) {
result.push({heavy: new Array(100_000).fill('💥')});
}
return result;
}

let result = allocate();
console.log(result.length);

let another1 = allocate();
console.log(another1.length);
let another2 = allocate();
console.log(another2.length);
let another3 = allocate();
console.log(another3.length);
let another4 = allocate();
console.log(another4.length);

This is fine:

result = allocate();
console.log(result.length);
result = allocate();
console.log(result.length);
result = allocate();
console.log(result.length);
result = allocate();
console.log(result.length);
result = allocate();
console.log(result.length);
result = allocate();
console.log(result.length);
result = allocate();
console.log(result.length);

Closures Cause Memory Leaks

This will crash:

function allocate() {
const result = [];
for (let i = 0; i < 2500; i++) {
result.push({heavy: new Array(100_000).fill('💥')});
}
return result;
}
function closure(value) {
const getLength = () => value.length;
return getLength;
}

const fn1 = closure(allocate());
console.log(fn1()); // 2500

const fn2 = closure(allocate());
console.log(fn2()); // 2500

const fn3 = closure(allocate());
console.log(fn3()); // 2500

const fn4 = closure(allocate());
console.log(fn4()); // 2500

This is fine:

function closure(value) {
const getLength = () => value.length;
return getLength;
}

const fn1 = closure(allocate());
console.log(fn1()); // 2500

const fn2 = closure(allocate());
console.log(fn2()); // 2500

const fn3 = closure(allocate());
console.log(fn3()); // 2500

const fn4 = closure(allocate());
console.log(fn4()); // 2500

Event Handlers

Foundation:

function allocate() {
const result = [];
for (let i = 0; i < 2500; i++) {
result.push({ heavy: new Array(100_000).fill('💥') });
}
return result;
}

const handlers = {
get onMove() {
const memory = allocate();
return () => memory.length;
}
};

const listeners = [];
function addEventListener(callback) {
listeners.push(callback);
console.log('listener added');
return callback
}

function removeEventListener(callback) {
const index = listeners.indexOf(callback);
if (index > -1) {
listeners.splice(index, 1);
console.log('listener removed');
}
}
let fn;

Buggy code:

// onPaintClick
addEventListener(handlers.onMove);

// onPaintClick
addEventListener(handlers.onMove);

// onPaintClick
addEventListener(handlers.onMove);

// onPaintClick
addEventListener(handlers.onMove);

Fixed code:

// onPaintClick
if (fn) removeEventListener(fn);
fn = addEventListener(handlers.onMove);

// onPaintClick
if (fn) removeEventListener(fn);
fn = addEventListener(handlers.onMove);

// onPaintClick
if (fn) removeEventListener(fn);
fn = addEventListener(handlers.onMove);

// onPaintClick
if (fn) removeEventListener(fn);
fn = addEventListener(handlers.onMove);
javascript
typescript
react
playwright

Enjoy free content straight from your inbox 💌

No spam, unsubscribe at any time.

Transcript

00:00

A memory leak is a programming language term used when a program holds onto memory that it doesn't intend to use anymore. Just like a water leak, wastes water, a memory leak, wastes memory, a memory leak can slow down a program as it continues to request more and more system resources. And over time it can lead to an out of memory error causing the program to crash. To demonstrate a memory leak, consider a simple function that allocates a lot of memory. It creates an array of 2,500 items where each item is a heavy item, which itself is an array of a hundred thousand items filled with the bank

00:37

emoji. Allocating memory by itself is not going to be a memory leak, but holding onto a value after you are done with it is a memory leak. For example, if all that we cared about was to read the length of the result, after we are done with that reading, we should get rid of the result as we no longer need that value anymore. If we don't do that and just keep creating more variables for more allocations and not getting rid of those variables, then we will eventually run out of memory. Let's demonstrate that by executing this code, you can see that we can allocate memory and we can read the length of the

01:10

results. However, now you can see that the J skip run time is struggling and in fact it will exit with an out of memory error. If we scroll up a bit, you can see the error that we crashed with. It is JavaScript heap out of memory. As we saw in our garbage collection tutorial, JavaScript manages memory for us. So fixing a memory leak is a simple matter of letting go of resources that you no longer intend to use. For example, scoping your variables only to functions where you use them or even setting a variable to null when you are done with its value. In this simple example, as soon as we assign results to a different value,

01:46

the previous value is available for garbage collection. So we can allocate as much memory as we want and store that into different results. And once we are done reading its strength, we can reuse that variable for something else. And now if you execute this code, even though it is allocating a lot more memory than it was before, all that memory that we do not use anymore can be garbage collected and the program runs to completion successfully. It can be argued that the key reason for the success of JavaScript is its support fore closures, but sadly, it's also the number one reason for a memory leak in JavaScript.

02:20

This is because functions can have implicit strong references to variables outside of their scope, which prevents their garbage collection. Here's an example of a simple function that takes a value and then wants to keep a strong reference to it because it intends to use it in a local function. We return the get length function from our closure, and as long as this get length function is in scope, the original value is also going to stay in scope. So we invoke closure with some memory allocated for the value. And as long as the return function FN one is going to be in scope, the original value is going to be in scope.

02:53

And we can see that because we can use FN one to read the length of the original value. So every single time we invoke the closure function with the value, the return function is going to hold onto that value. And if we do it a few too many times and execute this code, it will eventually run out of memory and the program will crash with an out of memory error. Now of course, our particular functions are holding on to very big values, but I wanted to make clear the fact that a function can increase the lifetime of a value. So essentially until we get rid of the function,

03:26

that value is going to stay around in memory. The solution for values being held by closures is the same as any other memory leak. You need to think about which values you don't need anymore. For example, you can discard the function or discard the references to the data within the function. As an example, instead of keeping a reference to the value, what we could do is we could note down the length of the value by itself and then within the function that we are returning, we only reference a length and there are no more references to value once this particular function returns. So now if you run this quarter again,

04:00

even though we are holding onto the function get length, it is not referencing value. It's referencing the simple number and therefore the value itself can be garbage collected. And our program executes without any issues we've seen that functions hold onto memory for external variables they reference due to closures, but it'll not make your program crash as long as you don't store too many functions. But we can end up in this silly situation by mistake when we are adding event listeners on some interaction but not removing the event. Listeners that are no longer relevant consider the simple example of a Photoshop style application. When the user clicks on the pinch tool,

04:36

we want to add an event listener that handles all cursor moves. If we add an event listener every single time, the user clicks on the pinch tool, then we will end up with lots of event listeners each with their own memory preventing garbage collection. So the memory consumption of our application will continue to go up and up. And if we have enough event listeners referencing enough values, then our program will eventually run out of memory and crash. The solution to this problem is pretty simple. Whenever we are passing around functions for event handlers, we want to make sure that we unsubscribe that if it is no longer relevant. This particular ad event listener gives us back a function which we can use to

05:12

unsubscribe. So every single time we make a new subscription, we make sure if you already have a subscription present, we remove that using Remove Event listener. This will ensure that Ad Event listener is not referencing functions that it no longer needs and they can be garbage collected. And now if you run this code again, every single time a new subscription is added, the previous subscription is removed, which means that the previous function can be garbage collected and we don't have a memory leak in our code anymore. Here is a simple takeaway from this tutorial. Don't hold onto references to data or functions which you no longer need.

05:46

This allows the garbage collector to jump in from time to time to clear up any unused resources and this will keep your JavaScript programs snippy and efficient and your users happy. As always, thank you for joining me and I will see you in the next one.

Professional Modern JavaScript

Professional Modern JavaScript

1.Course Intro
free
⏱️ 1:13
2.Setup & Tooling
free
⏱️ 3:32
3.Debugger Statements and Breakpoints
free
⏱️ 2:17
4.Primitive Data Types and Values
free
⏱️ 3:06
5.JavaScript Variables - let and const
free
⏱️ 4:50
6.Comments in JavaScript
free
⏱️ 2:55
7.JavaScript Identifer Naming
free
⏱️ 2:52
8.Using TypeScript
free
⏱️ 4:26
9.JavaScript String Masterclass
free
⏱️ 9:29
10.JavaScript Boolean Type
⏱️ 6:45
11.Missing Guide to JavaScript Numbers
⏱️ 15:28
12.JavaScript Objects Demystified
⏱️ 13:33
13.Functions in JavaScript
⏱️ 20:25
14.JavaScript Arrays Masterclass
⏱️ 22:31
15.JavaScript If Else Statements and Best Practices
⏱️ 6:13
16.JavaScript Conditional Expressions
⏱️ 8:38
17.JavaScript Loose vs Strict Equality
⏱️ 4:02
18.Truthy vs Falsy in JavaScript
⏱️ 3:44
19.Concept of JavaScript Nullish and Unification
⏱️ 5:51
20.JavaScript Classes - Object Oriented Programming
⏱️ 10:30
21.JavaScript Error Handling and Exceptions
⏱️ 13:21
22.JavaScript Nullish Operators
⏱️ 5:48
23.JavaScript Switch Statement Masterclass
⏱️ 8:07
24.JavaScript For Loop Iteration Simplified
⏱️ 10:59
25.JSON Masterclass
⏱️ 7:59
26.JavaScript While and Do While Loops
⏱️ 2:52
27.JavaScript Date and Time Simplified
⏱️ 13:16
28.this in JavaScript
⏱️ 12:04
29.JavaScript Tagged Templates Masterclass
⏱️ 5:48
30.Promises in JavaScript
⏱️ 10:01
31.JavaScript Async Await Masterclass
⏱️ 9:00
32.JavaScript Symbols Demystified
⏱️ 7:25
33.JavaScript Iterators and Iterables
⏱️ 8:50
34.JavaScript Generators Simplified
⏱️ 9:17
35.JavaScript Prototype - The Secret Guide
⏱️ 11:21
36.JavaScript Set Builtin Data Structure
⏱️ 9:52
37.JavaScript Map Builtin - HashMap Magic
⏱️ 10:38
38.JavaScript Deferred Promise Pattern - withResolvers
⏱️ 3:35
39.Cloning and Deep Copying in JavaScript
⏱️ 3:14
40.JavaScript Async Await Sequencing and Execution Masterclass
⏱️ 10:31
41.JavaScript Memory Management Masterclass
⏱️ 5:26
42.JavaScript WeakMap Demystified
⏱️ 8:58
43.JavaScript bigint Masterclass
⏱️ 5:35
44.JavaScript WeakSet Explained with Examples
⏱️ 7:47
45.JavaScript Regular Expressions Masterclass
⏱️ 17:54
46.JavaScript Weak References Demystified
⏱️ 5:29
47.JavaScript Memory Leaks Demonstrations and Fixes
⏱️ 6:01
48.Semicolon Free Coding in JavaScript
⏱️ 3:46
49.JavaScript Modules Masterclass
⏱️ 11:36