Transcript of There is garbage in our code - Talks by Softbinator
There's garbage in our code
Talks by Softbinator Adrian Oprea / @opreaadrian
I am
• Software over-engineer
• Deprived of sleep
• In love with JavaScript
• Docker fanboy :)
MEMORY MANAGEMENT
IN THEORY...
THE ACT OF MANAGING MEMORY AT THE SYSTEM LEVEL
DYNAMIC ALLOCATION / DE-ALLOCATION
MEMORY IS FREED FOR REUSE WHEN NO LONGER NEEDED
IN THE WILD...
ALL HIGH-LEVEL PROGRAMMING LANGUAGES IMPLEMENT SOME FORM OF AUTOMATIC MEMORY MANAGEMENT
AUTOMATIC
JAVA JAVASCRIPT .NET C++
GARBAGE COLLECTOR
MEMORY MANAGEMENT IN JAVASCRIPT
JAVASCRIPT
THE WORLD'S MOST MISUNDERSTOOD PROGRAMMING LANGUAGE
MEMORY • Is allocated at runtime
• Is freed whenever a certain threshold is reached
THE GARBAGE COLLECTOR KICKS IN WHEN YOU LEAST EXPECT
GC PAUSE...
PROBLEM #1
YOU HAVE NO CONTROL OVER THE COLLECTION PROCESS
PROBLEM #2
GARBAGE. COLLECTION. IS. VERY. EXPENSIVE.
BORED? LET'S LOOK AT 3 LINES OF CODE
SNIFFLES
GARBAGE COLLECTION ALGORITHMS
REFERENCE COUNTINGREFERENCE COUNTING
REFERENCE COUNTINGAVAILABLE IN PREVIOUS GENERATION BROWSERS (IE8 and below)
REFERENCE COUNTINGAN OBJECT IS ELIGIBLE FOR COLLECTION IF THERE ARE 0 REFERENCES POINTING TO IT
REFERENCE COUNTINGTHIS IS A NAIVE IMPLEMENTATION.
MARK AND SWEEP
REFERENCE COUNTINGSHIPS WITH ALL MODERN BROWSERS, SINCE 2012
REFERENCE COUNTINGHAS NO ISSUE COLLECTING CIRCULAR DEPENDENCIES(CYCLES)
REFERENCE COUNTINGINTRODUCES THE NOTION OF ROOT OBJECTS
WHERE IS THE GARBAGE?
GARBAGE COLLECTION IN V8
WHAT IS V8?
JAVASCRIPTVIRTUAL MACHINE NODE.JS
GOOGLE'S THE MONSTERBEHIND
FASTEST JAVASCRIPTMAINSTREAM
VIRTUAL MACHINE
GENERATIONAL GARBAGE COLLECTOR
GENERATIONAL WHAT?
Old 7 %
Young 93 %
MORTALITY RATE
V8 SPLITS OBJECTS IN TWO GENERATIONS
YOUNG GENERATION...
"FROM" and "TO" spaces
FAST ALLOCATION
FAST COLLECTION ~10ms
COLLECTION OCURRS WHEN THE TO SPACE IS FULL
OLD GENERATION
COLLECTION OCURRS RARELY
BIGGER IMPACT ON PERFORMANCE
IMPLICITLY TRIGGERS A YOUNG GENERATION COLLECTION
FULL COLLECTION
USES A MARK-COPMACT ALGORITHM
REACHABLE OBJECTS ARE MARKED
MARKED OBJECTS GET MOVED TO THE START OF THE HEAP - COPMACT
REWIRING OBJECT REFERENCES IS COSTLY
GARBAGE COLLECTION OPTIMISATIONS IN V8
IDENTIFYING LEAKS
EVIL DOMvar detached = null;
function fill() { for (var i = 0; i < 25; ++i) { var div = document.createElement('div'); div.data = new Array(10000); for (var j = 0, l = div.data.length; j < l; ++j) div.data[j] = j.toString(); detached.appendChild(div); }}
function start() { var p = document.getElementById("p"); detached = document.createElement("div"); p.appendChild(detached); p.removeChild(detached);
fill();}
start();
BETTER DOM
var detached = null;
function fill() { do stuff ...}
function start() { var p = document.getElementById("p"); detached = document.createElement("div"); p.appendChild(detached); p.removeChild(detached); // solution: EXPLICITLY SET TO NULL detached = null; fill();}
start();
EVIL XHR
function getText(url, callback) { var xhr = new XMLHttpRequest(); xhr.onload = function() { callback(xhr.responseText); } xhr.open('get', url, true); xhr.send(null);}
BETTER XHR
function getText(url, callback) { var xhr = new XMLHttpRequest(); xhr.onload = function() { callback(xhr.responseText); xhr = null; } xhr.open('get', url, true); xhr.send(null);}
EVIL CLOSURES
// catalogData is a large objectfunction getActiveItems(catalogData) { var activeItems = processCatalogData(catalogData);
function getItem(idx) { return activeItems[idx]; }
return getItem;}
BETTER CLOSURES
// catalogData is a large objectfunction getActiveItems(catalogData) { var activeItems = processCatalogData(catalogData);