JavaScript: Memory Leak Patterns

Memory is an essential part of any application irrespective of the technology behind the scene. In particular with JavaScript it becomes more crucial as the browser handles the memory management for JavaScript application and we don’t have a full stack power of machine. Though the browsers have improvised over a period of time, but still memory management is a bottleneck and consumes a lot of time to investigate the issues.
With freedom comes the responsibility, JavaScript is flexible to use in terms of managing the memory through code. As a JavaScript developer we don’t have to worry about when to allocate or de-allocate memory for application variables unlike in other languages i.e. C, C++ etc.
Memory leaks are valid but unwanted scenarios that bothers almost every developer. The consequences result into a variety of problems be it Low performance, Application crash, or affecting other applications.

What is a Memory Leak?

Memory leak is a phenomenon where memory is not reclaimed from objects, no longer required by the application code. In other words, memory unused by the application is not sent back to the free memory pool of system because of any reason is technically termed as Memory Leak. Memory leak generally comes as an unrevealed aspect of application.

Common JavaScript Leak patterns

There are few common patterns in application code that might result into Memory Leaks, even if not coded intentionally.

  1. Unintentional Global variables: In JavaScript creating global variables is very easy. Just assign a value in a variable that is not declared with a var keyword and you global variable is ready to be used across the application.function test() {
    global1 = "this is a hidden global variable";
    this.global2 = "this is a still hidden global variable"; //this points to the Window context
    }
    test(); //function call
  2. Unclosed setInterval & setTimeout: JavaScript developers often use these timer functions to perform tasks periodically e.g. change slides every 3 seconds in an UI Slider control. There are chances that these timers are not closed properly and hence result into a memory leak.var slideContent = "This is a very long string perhaps 5000 characters long.";
    var stopInterval=false;
    setInterval(function() {
    var slider = document.getElementById('slider');
    slider.innerHTML = slideContent;
    if(stopInterval)
    return false; //return false is not the solution to every problem, better clearInterval
    }, 3000);
    //down the line lets say we want to stop the slider timer
  3. Circular DOM references: JavaScript and DOM are referenced to each other quite often. This makes it easy for JavaScript developer to introduce the interactive behaviour in application. On the side note, this could lead to a memory leak if not used carefully.var slideContent = "This is a very long string perhaps 5000 characters long.";
    var slider = document.getElementById('slider');
    var startButton=document.getElementById(‘startButton’);
    startButton.addEventListener(‘click’,function(){
    slider.innerHTML = slideContent;
    });
    //down the line let’s say we want to remove the button instance
    document.body.removeChild(startButton); // this will just remove the button but not the click handler, causing the ‘slideContent’ to be in
  4. Closures: Closure is an inner function in JavaScript world which has access to its parent scope as well. Most of the developers use it to avoid scope level mess and modularize the application code. Closures can access the parent scope, sometimes resulting into an unintentional memory leak.function outerFunction(){
    var bigData = "This is a very long string perhaps 5000 characters long.";
    this.innterFunction = function(){
    console.log(bigData);//since the bigData is referenced here, it is not eligible for garbage collection.
    //no further usage of bigData afterwords, just the console log was put to check the value. This little mistake keeps the bigData alive and result into memory leak.
    };
    }
    //instantiate outerFunction
    var oFunction=new outerFunction();

What Next?

Most of the memory leak in JavaScript happens due to the above mentioned patterns. There are techniques and tools available to detect the memory leak and resolve it further. Chrome Dev Tools offer variety of tools to detect the memory leaks, identify the application code areas that result in leaks.
So next time you hit a memory leak, try to check for these patterns in your code. It is a good practice to look for these patterns first and then use tools to get into details.
We will focus on the resolution strategies for the memory leak patterns in the next article.Memory is an essential part of any application irrespective of the technology behind the scene. In particular with JavaScript it becomes more crucial as the browser handles the memory management for JavaScript application and we don’t have a full stack power of machine. Though the browsers have improvised over a period of time, but still memory management is a bottleneck and consumes a lot of time to investigate the issues.
With freedom comes the responsibility, JavaScript is flexible to use in terms of managing the memory through code. As a JavaScript developer we don’t have to worry about when to allocate or de-allocate memory for application variables unlike in other languages i.e. C, C++ etc.
Memory leaks are valid but unwanted scenarios that bothers almost every developer. The consequences result into a variety of problems be it Low performance, Application crash, or affecting other applications.

What is a Memory Leak?

Memory leak is a phenomenon where memory is not reclaimed from objects, no longer required by the application code. In other words, memory unused by the application is not sent back to the free memory pool of system because of any reason is technically termed as Memory Leak. Memory leak generally comes as an unrevealed aspect of application.

Common JavaScript Leak patterns

There are few common patterns in application code that might result into Memory Leaks, even if not coded intentionally.

  1. Unintentional Global variables:In JavaScript creating global variables is very easy. Just assign a value in a variable that is not declared with a var keyword and you global variable is ready to be used across the application.
    function test() {
    global1 = "this is a hidden global variable";
    this.global2 = "this is a still hidden global variable"; //this points to the Window context
    }
    test(); //function call
  2. Unclosed setInterval & setTimeout: JavaScript developers often use these timer functions to perform tasks periodically e.g. change slides every 3 seconds in an UI Slider control. There are chances that these timers are not closed properly and hence result into a memory leak.var slideContent = "This is a very long string perhaps 5000 characters long.";
    var stopInterval=false;
    setInterval(function() {
    var slider = document.getElementById('slider');
    slider.innerHTML = slideContent;
    if(stopInterval)
    return false; //return false is not the solution to every problem, better clearInterval
    }, 3000);
    //down the line lets say we want to stop the slider timer
  3. Circular DOM references: JavaScript and DOM are referenced to each other quite often. This makes it easy for JavaScript developer to introduce the interactive behaviour in application. On the side note, this could lead to a memory leak if not used carefully.var slideContent = "This is a very long string perhaps 5000 characters long.";
    var slider = document.getElementById('slider');
    var startButton=document.getElementById(‘startButton’);
    startButton.addEventListener(‘click’,function(){
    slider.innerHTML = slideContent;
    });
    //down the line let’s say we want to remove the button instance
    document.body.removeChild(startButton); // this will just remove the button but not the click handler, causing the ‘slideContent’ to be in
  4. Closures: Closure is an inner function in JavaScript world which has access to its parent scope as well. Most of the developers use it to avoid scope level mess and modularize the application code. Closures can access the parent scope, sometimes resulting into an unintentional memory leak.function outerFunction(){
    var bigData = "This is a very long string perhaps 5000 characters long.";
    this.innterFunction = function(){
    console.log(bigData);//since the bigData is referenced here, it is not eligible for garbage collection.
    //no further usage of bigData afterwords, just the console log was put to check the value. This little mistake keeps the bigData alive and result into memory leak.
    };
    }
    //instantiate outerFunction
    var oFunction=new outerFunction();

What Next?

Most of the memory leak in JavaScript happens due to the above mentioned patterns. There are techniques and tools available to detect the memory leak and resolve it further. Chrome Dev Tools offer variety of tools to detect the memory leaks, identify the application code areas that result in leaks.
So next time you hit a memory leak, try to check for these patterns in your code. It is a good practice to look for these patterns first and then use tools to get into details.
We will focus on the resolution strategies for the memory leak patterns in the next article.[:]