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


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


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



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