Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript: should I worry about memory leaks in 2011?

The topic of memory leaks in JavaScript is not brought up often. However, I stumbled upon this article, written in 2007. The authors state:

Internet Explorer and Mozilla Firefox are the two Web browsers most commonly associated with memory leaks in JavaScript.

Should I still be worrying about JavaScript memory leaks in 2011? If so, what should I be careful about?

like image 620
Randomblue Avatar asked Sep 11 '11 20:09

Randomblue


People also ask

Can JavaScript cause memory leak?

If your JavaScript application is experiencing frequent crashes, high latency, and poor performance, one potential cause could be memory leaks.

What is the main cause of memory leaks?

A memory leak starts when a program requests a chunk of memory from the operating system for itself and its data. As a program operates, it sometimes needs more memory and makes an additional request.

Which of the following can be done to reduce memory leakage?

Use reference objects to avoid memory leaks ref package, you can work with the garbage collector in your program. This allows you to avoid directly referencing objects and use special reference objects that the garbage collector easily clears. The special subclasses allow you to refer to objects indirectly.


4 Answers

A good javascript developer would be aware of various design patterns that can lead to memory leaks and you'd avoid coding anything that could turn in to a leak in pretty much all the pages you code.

For example, keeping a reference to any DOM object in a javascript variable will keep that DOM object alive in memory even if it's long since been removed from the DOM and you intended for it to be freed.

Practically speaking, leaks are only significant in some circumstances. Here's where I specifically worry about them:

  1. Anything I'm doing repetitively on a timer, particularly if it can be left running for a long time. For example, if you have a slideshow that might just loop forever, you have to make absolutely sure that nothing in the slideshow is an accumulating leak of either JS or DOM objects.
  2. A web page that works like an app and the user may stay on the same page for a long time, interacting with the page, doing ajax calls, etc... For example a web mail app might be open and on the same actual browser document for a very long time doing lots and lots of user and server interactions.
  3. A web page that regularly creates and destroys lots of DOM elements like something that regularly uses ajax to fetch a bunch of new HTML.

Places where I don't really worry about leaks:

  1. A web page that doesn't have a long running set of interactions the user can do.
  2. A web page that doesn't stay on screen very long before some other page is loaded or this page is reloaded.

Some of the key things I keep an eye out for.

  1. Any lasting JS variables or properties that contain references to DOM elements when DOM elements are being created/destroyed.
  2. Any properties of a DOM object that contain references to other DOM objects or references to JS objects that contain reference to other DOM objects (this can create circular references and cross references between JS/DOM that some older browsers have trouble freeing).
  3. Any large data structures that I load for temporary use. I make sure that no references to these large data structures are every kept around.
  4. Any data caches. Make sure nothing really large gets cached that you don't want cached. Make sure all caches that get used repeatedly don't accumulate forever and have some sort of aging mechanism to get rid of old objects.
like image 160
jfriend00 Avatar answered Oct 12 '22 09:10

jfriend00


Yes, memory leaks are definitely a problem in JavaScript, since circular references are indeed possible. A very common source of memory leaks is the use of closures. As an example, consider:

var outerFunction = function(param1, param2, param3) {
     var innerFunction = function() {};
     return innerFunction;
};

It is possible for the above to leak the parameters, since innerFunction holds a reference to the scope in which it was constructed, which includes the parameters to that frame.

While it is easy for these sorts of things to go unnoticed on many desktop computers, where there is plenty of RAM, this is actually something that can be very obvious on devices with limited RAM (e.g. a mobile phone or a set top box). As an anecdotal example, a couple websites that shall remain unnamed used to crash on me quite frequently when visited from my TV, which has very limited RAM.

Note that these problems are with the JavaScript code written by web developers. Memory leaks in the underlying JavaScript interpreters, while possible, are far less of an issue, and isn't something that web developers can reasonably concern themselves about, since that's the job of the browser writers.

like image 43
Michael Aaron Safyan Avatar answered Oct 12 '22 09:10

Michael Aaron Safyan


NO.

More complete answer: maybe. The fact you are asking so vaguely is a strong signal that you personally are unlikely to need to worry.

In practice, the vast majority of JavaScript code simply doesn't worry about it, and doesn't need to worry about it because only in particular circumstances do memory leaks in pages end up affecting users. The browser and frameworks cover your arse pretty well.

There are only a few questions you need to answer:

Q: Are you supporting a rich single page application that uses JavaScript heavily?

If not, then don't waste your time worrying. If you (or your QA, or your clients) find a memory over-usage issue with a page then fix it when it comes up.

Q: Do you need to support mobile devices, and you have heavy javascript usage?

Mobile devices have limited memory and extra care needs to be taken.

If you ARE developing a JavaScript heavy application, and you need to worry about memory usage, then...

The issue of "dirty" references to objects that cause JavaScript objects and DOM objects to never get garbage collected is important to certain types of JavaScript applications. Caches that grow forever, unexpected global references, and unexpected references inside closures can be a problem.

The Heap Snapshot tool in Chrome's Web Inspector can help.

Here is a git project that has a useful writup and walks the javascript objects it can: https://github.com/tlrobinson/leakhelper

There are other tools that help you, but I wrote my own over time: 1. our framework marks deleted widgets, so I wrote code to walk all arrays and objects from window or document looking for the paths to delected objects (javascript code can't walk closures but it definitely helped find some leaks). 2. Another trick I used was when widget x was deleted, I do a x.leakhelper = window.createElement('leakhelper') and setAttribute the oid of the widget, but not add the element into the document. If the DOM element is not garbage collected then the widget must have a dangling reference to it somewhere. In IE use window.collectGarbage() to force the GC, and use sIEve to detect the leaked DOM element (I found sIEve to be really useful).

Obsolete question: Do you need to strongly support either IE6 or IE7 AND you use JavaScript heavily? Most of the scary leaks you used to read about only occur in < IE8. If you are supporting IE6 or IE7 then you need good luck and perseverence (all frameworks leak, and it is hard to write code that doesn't even with a perfect framework - I ended up writing my own IE leak prevention code for our production use for IE6/7 users). The IE6/IE7 leaks can last even after you close your page - which is why they are so nasty.

like image 7
robocat Avatar answered Oct 12 '22 08:10

robocat


Well, people still use old versions of IE. So beware of circular references, because IE has severe problems with that. I believe the common mistake in that regard is to reference an HTML element in a closure that is inside an event handler to that element. Just set the variable referring to the element to null and it'll be fine.

like image 1
Ry- Avatar answered Oct 12 '22 09:10

Ry-