Memory Issues


just remember

@naugtur, meet.js 11.2013

Allocated for today:


  • Memory allocation and garbage collection
  • Memory leaking
  • Tools for patching up memory leaks
  • Sources of memory leaks

What's the problem?

Relevant data types

  • Primitives
  • Objects (thay can hold references to things)
  • Native/external stuff (mostly DOM)

Garbage collection

Young generation
New objects, frequent garbage collection

Old generation
Long lasting objects, garbage collection is rare, but done in parallel to JS execution

Garbage collection

  1. Man, that new allocation was too much.
  2. Let's destroy everything!
  3. Ok, but now I'm missing something.
    I want it back.

Objects and structures referenced from global root are copied back in.

Popular misconceptions

  • no, delete keyword does not free memory
  • seriously, delete just slows you down (changes hidden class)
  • no, setting object to null doesn't remove the object, it changes the reference

How it works

NEW SLIDE!

    var aBoy = { name: "Johny" },
        aGirl = { name: "Sue" },
        anAnimal={ name: "Garfield" };
                
    aBoy = null; //Johny can now be garbage-collected
    aGirl = { name: "Lucy" }; //Sue can now be garbage-collected
    
    aGirl.ownsAnimal = anAnimal //we have a new reference to Garfield
    anAnimal = null; //a reference is removed, but it was not the only one
                     //Garfield can't be garbage-collected
                            
                        

Tools!

GMail was leaking so bad that Google is now pioneering in memory leaks debugging tools. True story :)

Demo time!

Let's leak something

Method 1

Programmer error

Collection of items is held in a variable that is scoped incorrectly, or the logic is bad.


            var module = (function(){ 
            var keptAsLongAsModuleLives = []; 
                return { 
                    init:function(someObject){ 
                        keptAsLongAsModuleLives.push(someObject); 
                        //do stuff 
                    } 
                } 
            })();
                            

Method 2

DOM leftovers

A single DOM node is referenced from somewhere and the whole tree cannot be collected (element.parentNode, remember?)

Examples

Method 3

Nobody's perfect

A library might have created a cache,
or it's the browser itself

And that's where it gets sad...


  • Update jQuery to latest version - they work on it
  • It's hard to isolate cases when browsers leak. You know it's happening when the heap is empty and the process still has 2GB of RAM
  • Some ancient history: IE leaks event handlers

Pooling

What if I'm not leaking, but I need thousands of objects for short periods of time? I'm implementing a minigun.

  • Create a set of empty objects you need
  • Make a getter that finds the first unused object and returns it
  • Inform when you don't need the object anymore
  • Reuse the same 20 objects without ever causing garbage collection

More!

Just forget it.

@naugtur, naugtur.pl