Javascript memory leaks

memory leak

a type of resource leak that occurs when a computer program incorrectly manages memory allocations in such a way that memory which is no longer needed is not released

Wikipedia

// value initialization
var n = 123; // allocates memory for a number
var s = "azerty"; // allocates memory for a string 

var o = {
  a: 1,
  b: null
}; // allocates memory for an object and contained values

// (like object) allocates memory for the array and 
// contained values
var a = [1, null, "abra"]; 

function f(a){
  return a + 2;
} // allocates a function (which is a callable object)

// function expressions also allocate an object
someElement.addEventListener('click', function(){
  someElement.style.backgroundColor = 'blue';
}, false);
// function calls
// allocates a Date object
var d = new Date(); 

// allocates a DOM element
var e = document.createElement('div'); 
// method calls
var s = "azerty";
var s2 = s.substr(0, 3); // s2 is a new string
// Since strings are immutable value, 
// JavaScript may decide to not allocate memory, 
// but just store the [0, 3] range.

var a = ["ouais ouais", "nan nan"];
var a2 = ["generation", "nan nan"];
var a3 = a.concat(a2); 
// new array with 4 elements being
// the concatenation of a and a2 elements

garbage collector

In computer science, garbage collection (GC) is a form of automatic memory management. The garbage collector, or just collector, attempts to reclaim garbage, or memory occupied by objects that are no longer in use by the program.

common patterns

DOM leaks via javascript

// store DOM in javascript
var item.element = document.createElement(“div”);
list.appendChild(item.element);


// sometimes later
list.removeAllChildren();

solution

// store DOM in javascript
var item.element = document.createElement(“div”);
list.appendChild(item.element);

// make sure to clean javascript objects 
item = null;

// sometimes later
list.removeAllChildren();

circular references

<script type="text/javascript">
    window.onload = function(){
	var obj = document.getElementById("innocentElement");
       	document.getElementById("innocentElement").myData=obj;
       	obj.bigString = new Array(1000)
                    .join(new Array(2000)
                    .join("XXXXX"));
     };   	
</script>
<div id="innocentElement">Innocent element</div>

solution

<script type="text/javascript">
    window.onload = function(){
	var obj = document.getElementById("innocentElement");
       	document.getElementById("innocentElement").myData=obj;
       	obj.bigString = new Array(1000)
                    .join(new Array(2000)
                    .join("XXXXX"));
        obj = null;
     };   	
</script>
<div id="innocentElement">Innocent element</div>

encapsulator leak

<script type="text/javascript">
function Encapsulator(element){
    //Assign member
    this.element = element;
 
    // circular reference
    element.myData = this;
}
 
function SetupLeak() {
    //this leaks
    new Encapsulator(document
                        .getElementById("innocentElement"));
}
</script>

clojure event leaks

<script type="text/javascript">
    window.onload = function(){
	var obj = document.getElementById("innocentElement");
        
        // leaky clojure
       	obj.onClick = function() {
            alert('Insert evil memory leak message here');
        };
     };   	
</script>
<div id="innocentElement">Innocent element</div>

solution

<script type="text/javascript">
    window.onload = function(){
	var obj = document.getElementById("innocentElemet");
       	obj.onClick = handleClick;
     };

    // safe external function
    function handleClick() {
        alert('I will not leak.');
    }   	
</script>
<div id="innocentElemet">Innocent element</div>

available tools

Chrome DevTools

Firefox about:memory

IE11 DevTools

Safari

??

how to detect

  • disable all plugins
  • isolate an action
  • attach lots of data to suspect items
  • repeat the action a lot of times

what to look for

and yet it leaks

chrome console leak



function leakThis(obj) {
    console.log(obj);
}

tim.js/memoryleaks

By Ilie Vasilica Ciotir

tim.js/memoryleaks

A presentation on javascript memory leaks made for the tim.js community.

  • 334