JS
memory management

and hunting memory leaks

@naugtur, meet.js 2016
## Some history How did it become an issue and how it seems solved now

The app that tought me about memory leaks

#coolstory

Garbage collection

  1. New allocation triggers GC
  2. Cleanup is done by not saving unreachable references

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

## It's more complicated than that - Incremental GC (FF16) - Generational GC (FF32) https://hacks.mozilla.org/2014/09/generational-garbage-collection-in-firefox/ - Scheduling GC (Chrome45) - Compacting GC (FF38) https://hacks.mozilla.org/2015/07/compacting-garbage-collection-in-spidermonkey/
## Generations - Young generation - collected often - Old generation - collected rarely, different algorithm

Scheduling GC


Smarter garbage collection for smoother browsing and less memory usage, 2015/12/08
V8 garbage collection deep dive

Compacting GC

Compacting Garbage Collection in SpiderMonkey
More compacting GC

Hidden classes

Nice explanatoin with more links
# Freeing memory

How it works

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
                  

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
## When a reference dies - Reference lifetime - Functional scope New engines forget unused references

Pooling

What if 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 returns the least recently used one
  • Overwrite its fields with new values
  • Reuse the same N objects without ever causing garbage collection

This really is only useful for things like particle animation

What's the problem?

## What's a leak?
### Leaving a reference to someting you expected to get garbage collected ```js var module = (function(){ var keptAsLongAsModuleLives = []; return { init:function(someObject){ keptAsLongAsModuleLives.push(someObject); //do stuff } } })(); ```
## What's not a leak, but could be worse? - canvas allocates all pixels on first use `rgba*width*height` - separate event handler assignment to each element of the list (kinda went away with backbone) - cache of items downloaded from the server
## Tools - heap snapshot + diff view - profiles -> allocation timeline - timeline -> memory - force GC - timeline -> trash icon - performance.memory (chrome) - process.memoryUsage() (Node.js) [Memory analysis vocabulary](https://developers.google.com/web/tools/chrome-devtools/memory-problems/memory-101)
# Training time
## Reading the heap Red nodes do not have direct references from JavaScript to them, but are alive because they’re part of a detached DOM tree. There may be a node in the tree referenced from JavaScript preventing the entire DOM tree from being garbage collected. Yellow nodes have direct references from JavaScript. There should be a chain of properties leading from the DOM window to the element.
## Good times - Browsers don't leak much anymore. - Popular libraries tend to prevent leaks - Popularity of functional programming reduces chance of leaking - Human error is the most common source of leaks

Forget!

@naugtur
http://naugtur.pl

Subscribe to my newsletter http://naugtur.pl/news and get:

  • notifications about events I organize before everyone else (think tickets)
  • access to learning resources I produce
  • no spam, less than 1 email a month on average