WHAT DOES WIKIPEDIA SAY?
“In computer science, a memory leak
occurs when a computer program
incorrectly manages memory
Memory leaks occure if memory is repeatedly allocated
without being freed again by the program.
WHAT IS MEMORY ALLOCATION
Memory allocation = Object creation:
... more ways to create objects
HOW IS MEMORY FREED IN
HOW DOES GARBAGE
Objects are eligible for Garbage Collection once they
cease to be "alive"
Each object referenced by a "living" object is alive
counted as alive
The garbage collector roots are alive per definition
→ A living object is is part of a retaining tree which starts
at a garbage collection root
Examples of Object References:
GARBAGE COLLECTOR ROOTS
What are the garbage collector roots?
Internals of the VM implementation
For our purposes: windowcan be treated like a root
MEMORY LEAKS IN
Memory leaks occur if objects are repeatedly created and
cannot be reclaimed by the garbage collector due to
HOW DOES YOUR
1. LINKED WEBPAGES, A LITTLE JS
ON EACH PAGE
Navigating between pages resets the VM
Script does not execute over extended periods of time
Leaks have no time to cause trouble
→ NOTHING TO WORRY ABOUT
2. SINGLE PAGE JS APPLICATION
All content generated by JS program
Program runs as long as the page is open
Small leaks accumulate
Browser swallows 100s MB of RAM before crashing!
→ POTENTIAL SHOWSTOPPER!
HOW TO AVOID LEAKS?
Simple answer: Always be sure to delete all references to
REFERENCES VIA SCOPE
1. Object stays referenced through garbagewhile foo
2. garbagegoes out of scope once footerminates
3. No more references to object → can be garbage
No big deal as long as we avoid global variables
REFERENCES THROUGH OBJECT
Object remains referenced via vault.entryeven after
Need either to reset vault.entryor remove all
references to vault
Take care that no other objects retain references to
unused objects — maps / registries, I'm looking at you :)
Object is referenced by the returned function closure
even after footerminates!
The object is only cleaned up after the function
referenced by baris garbage collected
With great power comes great responsibility: be careful
when passing around closures!
DANGEROUS SPECIAL CASE:
The event handler keeps a reference to the counter
We have no direct reference to the handler
Garbage collection will never happen!
Always leave a way to clean out event handlers (and do
it!), don't throw away those references!
DANGEROUS SPECIAL CASE:
DETACHED DOM TREES
We keep a reference to the newly created div in a global
... but remove it from the DOM when clearing its parent
Node remains referenced → detached DOM tree!
Take care to hold no references into DOM trees after they
For a healthy application, memory consumption should
Rise over time as objects are allocated
Go down when garbage is collected → sawtooth pattern
Baseline after garbage collection should not change
Growing consumption after GC indicates a leak
Capture a snapshot of the heap contests
Can be filtered by constructor
Living objects can be inspected
Allocated memory size
Differences between snapshots: what leaks?
Retaining trees: why does it leak?
Retaining tree allows to track down the references that
have to be cleaned out!
SOME HINTS FOR READING THE
The shortest path is usually most interesting
Inspect what you can — know your enemy
Follow the black objects; gray ones are internals
'context' indicates a function scope
'native' on a DOM node indicates an event handler
Take your time!
HEAP ALLOCATION TIMELINE
Shows allocation events
Allocations which have been freed turn light blue
Heap can be inspected filtered based on the time of
Allows to correlate heap state with events → identify the
code paths that leak
TRACKING INDIVUAL OBJECTS
Named constructors can be easily found in heap
Marker is not collected as long as trackedInstance
Allows to identify individual objects in heap
More generally: naming function makes heap snapshots
much easier to read
DEALING WITH LEAKY LIBRARIES
Assuming that the library is buggy, it could retain a
reference to someObject, leading to a leak.
Reference is now indirect via scope
Resetting scope.instancebreaks reference
The library can't prevent someObjectfrom being
Leak is reduced to scope object!
Profile memory usage early and often
Be extra careful with closures
Unbind event listeners
Be careful with registries
Consider object pooling