[Javascript ] ES6 Memory leak

5 issue for memory leak as I know from project.

·

4 min read

[Javascript ] ES6 Memory leak

Three types of memory leaking for JavaScript and two types of react.js issue

  1. Undeclared or accidental global variables

if we don't set any var let const it will turn to be global set, we can use 'use strict' to avoid it. the sample below

The undeclared variable creates a new variable within the global object. It causes a memory leak because the garbage collector cannot clear them.

error way

<script>
    function init(){
      bar = 'this is test';
    }
  </script>

correct way

 <script>
    function init(){
     this.bar = 'this is test';  
        // or 
      var bar = 'this is test'; 
    }
  </script>
  1. Forgotten timers or callbacks

if you accidentally use setTimeout setInterval in the function, they will keep calling

The undeclared variable creates a new variable within the global object. It causes a memory leak because the garbage collector cannot clear them.

  1. setTimeout and setInterval
  <script>
      var resource='default';
      function init() {
        setInterval(function(){
          resource='setTime';
          console.log(resource);
        },1000);
      }
      resource=null;
  </script>

This snippet does one thing: set resource value every 1 second. it cost memory leaks if you forget to clean your functional

  1. event listener

    Event listeners are attached to elements and remain in memory until explicitly removed. It causes a memory leak if an element with an attached event listener is removed from the DOM but not the listener.

    Remove event listeners and unsubscribe whenever you no longer need them to avoid this problem.

var element = document.getElementById('button');

function onClick(event) {
    element.innerHtml = 'text';
}

element.addEventListener('click', onClick);
// Do stuff
element.removeEventListener('click', onClick);
element.parentNode.removeChild(element);
// Now when element goes out of scope,
// both element and onClick will be collected even in old browsers that don't
// handle cycles well.
  1. Closures

    A key aspect of JavaScript development is closures: anonymous functions that capture variables from parent scopes

    Any variables in the outer function that are being used in the inner function will remain in memory until the closure is released. Keep closures to a minimum and release them when you no longer need them.

    error sample

var theThing = null;
var replaceThing = function () {
  var originalThing = theThing;
  var unused = function () {
    if (originalThing)
      console.log("hi");
  };
  theThing = {
    longStr: new Array(1000000).join('*'),
    someMethod: function () {
      console.log(someMessage);
    }
  };
};
setInterval(replaceThing, 1000);

This snippet does one thing: every time replaceThing is called, theThing gets a new object which contains a big array and a new closure (someMethod). At the same time, the variable unused holds a closure that has a reference to originalThing (theThing from the previous call to replaceThing). Already somewhat confusing, huh? The important thing is that once a scope is created for closures that are in the same parent scope, that scope is shared. In this case, the scope created for the closure someMethod is shared by unused. unused has a reference to originalThing. Even though unused is never used, someMethod can be used through theThing. And as someMethod shares the closure scope with unused, even though unused is never used, its reference to originalThing forces it to stay active (prevents its collection). When this snippet is run repeatedly a steady increase in memory usage can be observed. This does not get smaller when the GC runs. essenially, a linked list of closures is created (with its root in the form of the theThing variable), and each of these closures' scopes carries an indirect reference to the big array, resulting in a sizable leak.

additionally, react memory leak issue

  1. Async operation & state update: Assume, the user first makes an API call to fetch the data. Then user clicks on some link, which navigates to another page before request is completed. Now as soon as the API request is complete, it will look for the state to get updated which no longer exists.

  2. Infinite prefetching loop: UseEffect generally takes two arguments. The first is a callback function, and the second is a dependency array. When there is no second argument to useEffect, setting the state is repeated endlessly. As a result, memory leaks occur as system resources are drained.

Conclusion

in SPA framework, it starts to turn to be a problem for developing experience. this is a small tip to let me know what is the issue to cause my project doesn't have the unexpected issue.

Reference

https://auth0.com/blog/four-types-of-leaks-in-your-javascript-code-and-how-to-get-rid-of-them/

https://dotblogs.com.tw/kinanson/2017/05/11/140022

https://www.linkedin.com/in/vidhya1706/recent-activity/shares/

https://shawnlin0201.github.io/JavaScript/JavaScript-Garbage-Collection/