How to Detect Memory Leak Detection in JavaScript
-
the
Accidental Global Variable
Memory Leaks in JavaScript -
Use the
Use Strict;
to Avoid Memory Leak in JavaScript -
Use
"use strict";
to Avoid Memory Leak Caused by Global Variable in JavaScript -
Use
{once: true}
andremoveEventListener()
to Avoid Memory Leak Caused by Out of DOM References in JavaScript -
Memory Leak Caused by
Forgotten Callbacks or Timer
and Its Prevention Techniques -
How to Avoid
Forgotten Callbacks or Timer
in JavaScript
Memory leaks are no longer needed memory that is not returned to the free memory’s pool or Operating System.
There are three most common circumstances where memory leaks can occur: Accidental Global Variable
, forgotten callbacks or timer
, and out of DOM references
.
the Accidental Global Variable
Memory Leaks in JavaScript
The Accidental Global Variable
is not declared as global
variables. The garbage collector can’t collect them, which leads to a memory leak.
The name
variable is created as global window.name
, and its assigned space is never released.
function fn1() {
// `name` is not declared
name = new Array(99999999)
}
fn1();
Use the Use Strict;
to Avoid Memory Leak in JavaScript
function fn1() {
'use strict';
name = new Array(99999999)
}
fn1();
Output:
Unused
variables are unutilized that need to be removed or handled properly to free space in the memory.
The most crucial point is to find the memory that is no longer required.
JavaScript uses the garbage collector to determine whether a certain section of the code needs memory or not.
Many garbage collectors use the mark-and-sweep
algorithm.
Use "use strict";
to Avoid Memory Leak Caused by Global Variable in JavaScript
Use heap allocations
on the Memory
tab in the Chrome DevTools.
You can open DevTools in Chrome by pressing F12 or by going to Right Click
-> Inspect
-> Memory
.
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
</head>
<body>
<button id="leak-button">Start</button>
<button id="stop-leak">Stop</button>
<script>
var x=[];
var running = false;
function grow(){
x.push(new Array(1000000).join('x'));
if(running)
setTimeout(grow,1000);
}
$('#leak-button').click(function(){
running = true;
grow();
});
$('#stop-button').click(function(){
running = false;
});
</script>
</body>
</html>
OUTPUT:
Here, the script appends 10.000
nodes to the DOM
whenever the user clicks on the Start
button and pushes a string that holds million x
characters into the array.
The vertical partially blue lines show memory leaks even after pressing the stop
button.
Variable x
is the reason for memory leak because it is a global variable and occupies the space even it is no longer needed.
Use {once: true}
and removeEventListener()
to Avoid Memory Leak Caused by Out of DOM References in JavaScript
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
</head>
<body>
<button id="trigger">Trigger</button>
<script>
var clickElement = document.getElementById("click");
const hugeString = new Array(100000).join('x');
clickElement.addEventListener("click", function(){
// hugeString is kept in the scope of callback forever
document.write(hugeString);
});
</script>
</body>
</html>
OUTPUT:
An Active event
listener can prevent variables from being garbage collected.
Use removeEventListener()
or passing the third parameter as {once: true}
.
In this way, it is executed once. The listener
method will be automatically deleted.
Memory Leak Caused by Forgotten Callbacks or Timer
and Its Prevention Techniques
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
</head>
<body>
<script>
for (var i = 0; i < 100000; i++) {
var obj = {
call_again: function() {
var message = this;
var value = setTimeout(function() {
message.callAgain();
}, 100000);
}
}
obj.call_again();
obj = null;
}
</script>
</body>>
</html>
OUTPUT:
The timer callback
and its tied object obj
are not released until the timeout is finished.
The timer
can reset itself and execute forever. Therefore, the memory space will always be reserved and never be free.
How to Avoid Forgotten Callbacks or Timer
in JavaScript
By providing reference in setTimeout()
or setInterval()
and making a direct call to delete the function once they are not needed anymore.