SlideShare a Scribd company logo
Node.js behind: V8 engine & its optimizations
Agenda
• What is V8?
• Full-codegen
• Crankshaft
• TurboFan
• Ignition
• Optimizations & memory representation by examples
• Garbage collector & memory leaks
• Useful links
What is V8?
2010
Introduced
Crankshaft
2014
Introduced
TurboFan
2016
Introduced
Ignition
2015
TurboFan
enabled in Chrome 41
2017
Ignition
in Chrome 58 for tests
2008
Introduced
V8
2009
Introduced
Node.js
…
Compiler pipeline
What is V8?
Source
Bytecode Unoptimized code Optimized code
Parser Ignition Parser Full-codegen
Crankshaft
TurboFan
Parser
Deoptimize
Interpreted Baseline Optimized
Desired compiler pipeline
What is V8?
Source
Bytecode Optimized code
Parser Ignition
TurboFan
Deoptimize
Interpreted Optimized
Full-codegen
How full-codegen works?
• Compiles JS code directly to native code before executing it
• Needs to compile code as quick as possible
• It’s not optimizing code
• One function at a time, compiling just in time
• Uses Inline Caches to implement loads, stores calls, binary, unary and comparison
• Implementation of IC is stub, generated on the fly, can be cached for common cases
• Stub on beginning has no instructions, each missed call makes it more complicated
Full-codegen
Crankshaft
How Crankshaft works?
• Only selected "hot" functions are passed for optimizations.
• Hot: marked for optimization -> LazyRecompile -> optimizing
• Hot: uninitialized -> premonomorphic -> monomorphic
• Most of time will mark to optimize at second call
• Sometimes compiler will optimize it immediately (big loops) - on-stack replacement
• Builds Hydrogen control flow graph (SSA)
• Optimizes in Hydrogen graph (only part which can be in parallel to JS)
• Generates Lithium graph
• Emit native instructions
Crankshaft
Static single assignment form
Crankshaft
From: https://en.wikipedia.org/wiki/Static_single_assignment_form
x ← 5
x ← x - 3
x<3?
y ← x * 2
w ←y
y ← x - 3
w ← x - y
z ←x + y
x1 ← 5
x2 ← x - 3
x2<3?
y1 ← x2 * 2
w1 ← y1
y2 ← x2 - 3
w2 ← x2 - y?
z1 ←x2 + y?
Static single assignment form
Crankshaft
From: https://en.wikipedia.org/wiki/Static_single_assignment_form
x ← 5
x ← x - 3
x<3?
y ← x * 2
w ←y
y ← x - 3
w ← x - y
z ←x + y
x1 ← 5
x2 ← x - 3
x2<3?
y1 ← x2 * 2
w1 ← y1
y2 ← x2 - 3
y3 = Φ(y1,y2)
w2 ← x2 - y3
z1 ←x2 + y3
What is Crankshaft optimizing?
• Inline functions - when it’s safe and they are small
• Tag values - e.g. integer, double
• Analyze Uint32 - by default uses 31-bit for small signed integers, allow use of bigger
• Canonicalization - simplify
• Global Value Numbering (GVN) - eliminate redundancy
• Redundant bounds check elimination - remove unneeded checks for arrays
• Dead code elimination
Crankshaft
TurboFan
How TurboFan works?
• Uses „sea of nodes” concept
• Can work directly on byte code (works perfectly with Ignition)
• Machine code is emitted
• Able to easily handle more features (e.g. from ES6)
• More aggressive than Crankshaft
• Optimizes progressively
• Has scheduling algorithm
TurboFan
Ignition
How to enable Ignition?
• In Chrome it’s put on A/B tests or you can use flag disable-v8-ignition-turbo
• In Node.js 7+ use --ignition flag
Ignition
How Ignition works?
• It’s interpreter
• Compiles to byte code
• Reduce memory usage for compiling (important for mobile)
• Improve startup time
• Simplify compilation pipeline
• Perform some optimizations, e.g. remove dead-code
Ignition
Optimizations & memory representation
by examples
How tests were prepared?
• MacBook Pro (early 2015), i5 2.7GHz, 8GB DDR3
• Node.js 7.7.1 (V8 5.5.372.41)
• Time calculated by time node script.js
• Number of iterations vary in test cases
Optimizations & memory representation by examples
Try/catch
// Set up number of iterations
const iterations = 1e9
// Set up function for tests
function f () {
return 1 + 2 * 3 / 4
}
// Set up function which calls function
function test () {
for (var i = 0; i < iterations; i++) {
f(i)
}
}
try {
test()
} catch (e) {
// Do nothing
}
real: 0.663s user: 0.555s sys: 0.027s
Optimizations & memory representation by examples
// Set up number of iterations
const iterations = 1e9
// Set up function for tests
function f () {
return 1 + 2 * 3 / 4
}
// Set up function which calls function
function test () {
try {
for (var i = 0; i < iterations; i++) {
f(i)
}
} catch (e) {
// Do nothing
}
}
test()
real: 8.826s user: 8.496s sys: 0.071s
Try/catch
// Set up number of iterations
const iterations = 1e9
// Set up function for tests
function f () {
return 1 + 2 * 3 / 4
}
// Set up function which calls function
function test () {
for (var i = 0; i < iterations; i++) {
f(i)
}
}
try {
test()
} catch (e) {
// Do something
}
real: 0.663s user: 0.555s sys: 0.027s
Optimizations & memory representation by examples
// Set up number of iterations
const iterations = 1e9
// Set up function for tests
function f () {
return 1 + 2 * 3 / 4
}
// Set up function which calls function
function test () {
try {
for (var i = 0; i < iterations; i++) {
f(i)
}
} catch (e) {
// Do something
}
}
test()
real: 8.826s user: 8.496s sys: 0.071s
For..in
// Set up number of iterations
const iterations = 1e8
// Set up function for tests
function f () {
var obj = {}
var key
for (key in obj) {
// Do nothing
}
}
// Benchmark function
for (var i = 0; i < iterations; i++) {
f(1, 2, 3, 4, 5)
}
real: 1.416s user: 1.281s sys: 0.042s
// Set up number of iterations
const iterations = 1e8
// Set up function for tests
var key
function f () {
var obj = {}
for (key in obj) {
// Do nothing
}
}
// Benchmark function
for (var i = 0; i < iterations; i++) {
f(1, 2, 3, 4, 5)
}
real: 3.181s user: 2.868s sys: 0.055s
Optimizations & memory representation by examples
For..in
// Set up number of iterations
const iterations = 1e8
// Set up function for tests
function f () {
var obj = {}
var key
for (key in obj) {
// Do nothing
}
}
// Benchmark function
for (var i = 0; i < iterations; i++) {
f(1, 2, 3, 4, 5)
}
real: 1.416s user: 1.281s sys: 0.042s
// Set up number of iterations
const iterations = 1e8
// Set up function for tests
var key
function f () {
var obj = {}
for (key in obj) {
// Do nothing
}
}
// Benchmark function
for (var i = 0; i < iterations; i++) {
f(1, 2, 3, 4, 5)
}
real: 3.181s user: 2.868s sys: 0.055s
Optimizations & memory representation by examples
for..of vs classic for loop
// Set up number of iterations
const iterations = 1e8
// Set up data
const arr = [ 0, 1, 2, 3, 4 ]
// Set up function for tests
function f () {
for (var element of arr) {
// Do nothing
}
}
// Benchmark function
for (var i = 0; i < iterations; i++) {
f()
}
real: 13.879s user: 13.662s sys: 0.099s
// Set up number of iterations
const iterations = 1e8
// Set up data
const arr = [ 0, 1, 2, 3, 4 ]
// Set up function for tests
function f () {
for (var i = 0; i < arr.length; i++) {
var el = arr[i]
}
}
// Benchmark function
for (var i = 0; i < iterations; i++) {
f()
}
real: 0.722s user: 0.620s sys: 0.028s
Optimizations & memory representation by examples
for..of implementation
class Iterable {
constructor (...elements) {
this.els = elements || []
}
add (...elements) {
this.els.push(...elements)
}
*[Symbol.iterator] () {
yield* this.els
}
}
const a = new Iterable(1, 2, 3, 4)
for (let element of a) {
console.log(element)
}
class Iterable2 {
constructor (...elements) {
this.els = elements || []
}
add (...elements) {
this.els.push(...elements)
}
*[Symbol.iterator] () {
for (let i = 0; i < this.els.length; i++) {
yield this.els[i]
}
}
}
Optimizations & memory representation by examples
Mono & polymorphic
operations
// Set up number of iterations
const iterations = 1e9
// Set up function for tests
function f (x) {
return x + 'a'
}
// Set up testing values
const values = [ 0, 1, 2, 3, 4, 5 ]
const length = values.length
// Benchmark function
for (var i = 0; i < iterations; i++) {
var value = values[i % length]
f(value)
}
real: 7.325s user: 6.697s sys: 0.071s
// Set up number of iterations
const iterations = 1e9
// Set up function for tests
function f (x) {
return x + 'a'
}
// Warm function with different types of values
f(undefined), f(null), f('a'), f(true)
// Set up testing values
const values = [ 0, 1, 2, 3, 4, 5 ]
const length = values.length
// Benchmark function
for (var i = 0; i < iterations; i++) {
var value = values[i % length]
f(value)
}
real: 21.012s user: 20.271s sys: 0.159s
Optimizations & memory representation by examples
Mono & polymorphic
operations
// Set up number of iterations
const iterations = 1e9
// Set up function for tests
function f (x) {
return x + 'a'
}
// Set up testing values
const values = [ 0, 1, 2, 3, 4, 5 ]
const length = values.length
// Benchmark function
for (var i = 0; i < iterations; i++) {
var value = values[i % length]
f(value)
}
real: 7.325s user: 6.697s sys: 0.071s
// Set up number of iterations
const iterations = 1e9
// Set up function for tests
function f (x) {
return x + 'a'
}
// Warm function with different types of values
f(undefined), f(null), f('a'), f(true)
// Set up testing values
const values = [ 0, 1, 2, 3, 4, 5 ]
const length = values.length
// Benchmark function
for (var i = 0; i < iterations; i++) {
var value = values[i % length]
f(value)
}
real: 21.012s user: 20.271s sys: 0.159s
Optimizations & memory representation by examples
Mono & polymorphic
operations• Different types causes different native operations
• Monomorphic stub has only one case
• Megamorphic stub has more cases
• For different cases needs to cover „safety gates” to handle different types
Optimizations & memory representation by examples
Objects interpretation
// Set up number of iterations
const iterations = 1e9
const obj = { 0: 1 }
// Set up function for tests
function f (i) {
obj[0] = i
}
// Benchmark function
for (var i = 0; i < iterations; i++) {
f(i)
}
real: 0.837s user: 0.729s sys: 0.030s
// Set up number of iterations
const iterations = 1e9
const obj = { x: 1 }
// Set up function for tests
function f (i) {
obj.x = i
}
// Benchmark function
for (var i = 0; i < iterations; i++) {
f(i)
}
real: 0.579s user: 0.554s sys: 0.013s
Optimizations & memory representation by examples
Object representation in
memory• Hash tables (dictionaries) - used for difficult objects, slow
• Fast elements - object with integer indexes, handled differently (can be array), small
• Fast, in-object properties - create hidden classes, shared same structure (transitions)
• Methods & Prototypes - Functions go as constant_function to map
• Object can move from one representation to another
Optimizations & memory representation by examples
Hidden classes
Optimizations & memory representation by examples
function Point (x, y) {
// Map M0
// ”x”: Transition to M1 at offset 12
this.x = x
// Map M1
// ”x” at 12
// ”y”: Transition to M2 at offset 16
this.y = y
// Map M2
// ”x” at 12, ”y” at 16
// ”do”: Transition to M3 <doSomething>
this.do = doSomething
// Map M3
// ”x” at 12, ”y” at 16
// ”do”: Constant_Function <doSomething>
}
function doSomething (p) { /* ……… */ }
From: https://github.com/thlorenz/v8-perf
function Point (x, y) {
this.x = x
this.y = y
if (x > 10) {
this.big = true
}
}
// Map X
const a = new Point(5, 0)
// Map Y
const b = new Point(20, 0)
Hidden classes
Optimizations & memory representation by examples
function Point (x, y) {
// Map M0
// ”x”: Transition to M1 at offset 12
this.x = x
// Map M1
// ”x” at 12
// ”y”: Transition to M2 at offset 16
this.y = y
// Map M2
// ”x” at 12, ”y” at 16
// ”do”: Transition to M3 <doSomething>
this.do = doSomething
// Map M3
// ”x” at 12, ”y” at 16
// ”do”: Constant_Function <doSomething>
}
function doSomething (p) { /* ……… */ }
From: https://github.com/thlorenz/v8-perf
function Point (x, y) {
// Map M0
this.x = x
// Map M1
this.y = y
// Map M2
if (x > 10) {
this.big = true
// Map M3
}
}
// Map M2
const a = new Point(5, 0)
// Map M3
const b = new Point(20, 0)
Object representation
Optimizations & memory representation by examples
Determine type of variable
// Set up number of iterations
const iterations = 1e8
// Set up function for tests
function f () {
var attr = arguments
if (1 === 1) {
attr = [ 0 ]
}
}
// Benchmark function
for (var i = 0; i < iterations; i++) {
f(i)
}
// Set up number of iterations
const iterations = 1e8
// Set up function for tests
function f () {
var attr = arguments
var x = [ 1 ]
if (1 === 1) {
x = [ 0 ]
}
}
// Benchmark function
for (var i = 0; i < iterations; i++) {
f(i)
}
real: 3.696s user: 3.466s sys: 0.064s real: 1.679s user: 1.454s sys: 0.037s
Optimizations & memory representation by examples
Mutate arguments
// Set up number of iterations
const iterations = 1e9
// Set up function for tests
function f () {
// Modify arguments element
arguments[0] = 0
return arguments[0]
}
// Benchmark function
for (var i = 0; i < iterations; i++) {
f(1)
}
real: 31.372s user: 31.064s sys: 0.106s
// Set up number of iterations
const iterations = 1e9
// Set up array-like object to modify property
var dummy = { 0: 1, length: 1 }
// Set up function for tests
function f () {
// Modify dummy element
dummy[0] = 0
return arguments[0]
}
// Benchmark function
for (var i = 0; i < iterations; i++) {
f(1)
}
real: 1.854s user: 1.753s sys: 0.029s
Optimizations & memory representation by examples
Mutate arguments
// Set up number of iterations
const iterations = 1e9
// Set up function for tests
function f () {
// Modify arguments element
arguments[0] = 0
return arguments[0]
}
// Benchmark function
for (var i = 0; i < iterations; i++) {
f(1)
}
real: 31.372s user: 31.064s sys: 0.106s
// Set up number of iterations
const iterations = 1e9
// Set up array-like object to modify property
var dummy = { 0: 1, length: 1 }
// Set up function for tests
function f () {
// Modify dummy element
dummy[0] = 0
return arguments[0]
}
// Benchmark function
for (var i = 0; i < iterations; i++) {
f(1)
}
real: 1.854s user: 1.753s sys: 0.029s
Optimizations & memory representation by examples
Mutate arguments variables
// Set up number of iterations
const iterations = 1e9
// Set up function for tests
function f (arg) {
// Modify argument
arg = 0
return arguments[0]
}
// Benchmark function
for (var i = 0; i < iterations; i++) {
f(1)
}
real: 31.570s user: 31.233s sys: 0.128s
// Set up number of iterations
const iterations = 1e9
// Set up function for tests
function f (arg) {
// Modify argument
arg = 0
return arg
}
// Benchmark function
for (var i = 0; i < iterations; i++) {
f(1)
}
real: 0.699s user: 0.554s sys: 0.036s
Optimizations & memory representation by examples
Methods to find bottlenecks
Optimizations & memory representation by examples
• Find problems by profiler / timeline (e.g. Chrome DevTools)
• Since 6.3: node —inspect-brk: Inspect code with DevTools
• node —trace-opt: trace optimizations on functions
• node —trace-deopt: trace deoptimizations
• node —allow-natives-syntax: Native Syntax for advanced scripting with V8 access
• node —prof: Profile code, generates v8.log file
• node —prof-process v8.log
Profiling Node (isolate-xxx-v8.log)
Optimizations & memory representation by examples
[Shared libraries]:
ticks total nonlib name
9 0.2% 0.0% C:WINDOWSsystem32ntdll.dll
2 0.0% 0.0% C:WINDOWSsystem32kernel32.dll
[JavaScript]:
ticks total nonlib name
741 17.7% 17.7% LazyCompile: am3 crypto.js:108
113 2.7% 2.7% LazyCompile: Scheduler.schedule richards.js:188
103 2.5% 2.5% LazyCompile: rewrite_nboyer earley-boyer.js:3604
103 2.5% 2.5% LazyCompile: TaskControlBlock.run richards.js:324
96 2.3% 2.3% Builtin: JSConstructCall
...
[C++]:
ticks total nonlib name
94 2.2% 2.2% v8::internal::ScavengeVisitor::VisitPointers
33 0.8% 0.8% v8::internal::SweepSpace
32 0.8% 0.8% v8::internal::Heap::MigrateObject
30 0.7% 0.7% v8::internal::Heap::AllocateArgumentsObject
...
[GC]:
ticks total nonlib name
458 10.9%
Garbage collector
& memory leaks
What is Garbage Collector for?
• Delete data from memory when it’s no longer needed
• Garbage collector most of time may be slower than managing memory by self
• Program has to stop while garbage collector is working
• Make easier for developer to manage memory
Garbage collector & memory leaks
How does GC work?
• There is created tree of nodes (with dependencies)
• Everything what is accessible from root (all global objects, all in branches) is live
• New data is most of time temporary, so probably should be earlier destroyed
Garbage collector & memory leaks
Memory zones & collecting
garbage• Young generation = New space, Old generation = Old space
• After surviving for a while in new space, elements are moved to old space
• Allocation to old space is fast, but collecting there is slower
• On new space - scavenge collection, old - mark-sweep (or mark-compact)
• Marking can be processed in chunks
• There are 3 marking states:
• White - object not discovered by GC
• Grey - discovered, but not all neighbors processed
• Black - all of neighbors has been fully processed
Garbage collector & memory leaks
Collecting garbage
Garbage collector & memory leaks
root
a b
c d
Collecting garbage
Garbage collector & memory leaks
a b
c d
root
Collecting garbage
Garbage collector & memory leaks
d
root
a b
c
Collecting garbage
Garbage collector & memory leaks
root
a b
c d
// Remove pointer from 'a' to 'd'
a.property = null
Collecting garbage
Garbage collector & memory leaks
a b
c
root
// Remove pointer from 'a' to 'd'
a.property = null
d
Collecting garbage
Garbage collector & memory leaks
root
// Remove pointer from 'a' to 'd'
a.property = null
a b
c d
Collecting garbage
Garbage collector & memory leaks
a b
c
root
// Remove pointer from 'a' to 'd'
a.property = null
Memory zones
• New space - garbage collected quickly, 1-8MB space
• Old pointer space - objects which have pointers to other, moving from „new” after while
• Old data space - objects which contain raw data (objects, strings, arrays etc)
• Large object space - objects larger than size limit for other spaces, never moved
• Code space - JITed instructions, code objects
• Cell space, map space, property cell space - Cells, PropertyCells and Maps
Garbage collector & memory leaks
Memory leaks: examples
Garbage collector & memory leaks
function f () {
obj = {
a: 1,
b: 1
}
}
• It might be by accident
• It assigns to this element
• this may be global or window
• Assigned to root, so will not be removed
Memory leaks: examples
Garbage collector & memory leaks
// Get some data
var r = getData()
// Process data
function process () {
if (shouldProcess()) {
console.log(r.items)
}
}
// Do something in interval
setInterval(process, 10000)
• Intervals which uses some data
• When they are not needed - clear them
Memory leaks: examples
Garbage collector & memory leaks
var theThing = null
function replaceThing () {
var originalThing = theThing
var unused = function () {
if (originalThing) {
console.log("hi")
}
}
theThing = {
longStr: new Array(1000000).join('*'),
someMethod: function () {
console.log(someMessage)
}
}
}
setInterval(replaceThing, 1000)
• Closures can be bad
• unused keeps pointer to originalThing
• someMethod share closure with unused
• Keeps reference to old theThing
Memory leaks: how to detect
Garbage collector & memory leaks
• Generate heap dumps (record in Chrome, or e.g. use `heapdump` module)
• Chrome DevTools - JS Profiler: Comparison
• Compare two/three snapshots from different time - you will see what is left
From: http://bit.ly/2pcDTe9
Memory leaks: how to detect
Garbage collector & memory leaks
• Generate heap dumps (record in Chrome, or e.g. use `heapdump` module)
• Chrome DevTools - JS Profiler: Comparison
• Compare two/three snapshots from different time - you will see what is left
• Other way: use GCore
gcore `pgrep node`
> ::findjsobjects
object_id::jsprint
object_id::findjsobjects -r
Useful links
Useful links
• https://github.com/v8/v8 - V8 code mirror on GitHub
• https://v8project.blogspot.com/ - Blog with V8 insights
• http://v8-io12.appspot.com/ - V8 overview (2012)
• http://bit.ly/2oBGvht - Ignition presentation (2016)
• http://bit.ly/2p68bgf - measure and optimize GC for RAIL (2016)
• http://bit.ly/2q4fsfS - RisingStack article, pretty simple about GC (2016)
• http://bit.ly/2oBDXjk - Jay Conrod wrote series about V8 mechanisms (2012)
• http://darksi.de/d.sea-of-nodes/ - Sea of node explanation
• https://github.com/thlorenz/v8-perf/ - Some stuff about V8 (2014)
Thanks for attention!
Something more? Catch me at drusnak@g2a.com
Find presentation at:
https://bit.ly/node-js-behind

More Related Content

What's hot

OpenCL 3.0 Reference Guide
OpenCL 3.0 Reference GuideOpenCL 3.0 Reference Guide
OpenCL 3.0 Reference Guide
The Khronos Group Inc.
 
PHP unserialization vulnerabilities: What are we missing?
PHP unserialization vulnerabilities: What are we missing?PHP unserialization vulnerabilities: What are we missing?
PHP unserialization vulnerabilities: What are we missing?
Sam Thomas
 
Testing in-python-and-pytest-framework
Testing in-python-and-pytest-frameworkTesting in-python-and-pytest-framework
Testing in-python-and-pytest-framework
Arulalan T
 
New PHP Exploitation Techniques
New PHP Exploitation TechniquesNew PHP Exploitation Techniques
New PHP Exploitation Techniques
RIPS Technologies GmbH
 
Effective testing with pytest
Effective testing with pytestEffective testing with pytest
Effective testing with pytest
Hector Canto
 
Understanding .Net Standards, .Net Core & .Net Framework
Understanding .Net Standards, .Net Core & .Net FrameworkUnderstanding .Net Standards, .Net Core & .Net Framework
Understanding .Net Standards, .Net Core & .Net Framework
punedevscom
 
LLVM Register Allocation
LLVM Register AllocationLLVM Register Allocation
LLVM Register Allocation
Wang Hsiangkai
 
Typescript ppt
Typescript pptTypescript ppt
Typescript ppt
akhilsreyas
 
Shootout! Template engines for the JVM
Shootout! Template engines for the JVMShootout! Template engines for the JVM
Shootout! Template engines for the JVM
Jeroen Reijn
 
OO Design and Design Patterns in C++
OO Design and Design Patterns in C++ OO Design and Design Patterns in C++
OO Design and Design Patterns in C++
Ganesh Samarthyam
 
The redux saga begins
The redux saga beginsThe redux saga begins
The redux saga begins
Daniel Franz
 
From object oriented to functional domain modeling
From object oriented to functional domain modelingFrom object oriented to functional domain modeling
From object oriented to functional domain modeling
Mario Fusco
 
Advanced Object-Oriented/SOLID Principles
Advanced Object-Oriented/SOLID PrinciplesAdvanced Object-Oriented/SOLID Principles
Advanced Object-Oriented/SOLID Principles
Jon Kruger
 
TypeScript - An Introduction
TypeScript - An IntroductionTypeScript - An Introduction
TypeScript - An Introduction
NexThoughts Technologies
 
TypeScript
TypeScriptTypeScript
Big picture of category theory in scala with deep dive into contravariant and...
Big picture of category theory in scala with deep dive into contravariant and...Big picture of category theory in scala with deep dive into contravariant and...
Big picture of category theory in scala with deep dive into contravariant and...
Piotr Paradziński
 
FE로 취업 전에 알았으면 좋았을 것들
FE로 취업 전에 알았으면 좋았을 것들FE로 취업 전에 알았으면 좋았을 것들
FE로 취업 전에 알았으면 좋았을 것들
Taegon Kim
 
Ruby Programming Language - Introduction
Ruby Programming Language - IntroductionRuby Programming Language - Introduction
Ruby Programming Language - Introduction
Kwangshin Oh
 
ES6: The Awesome Parts
ES6: The Awesome PartsES6: The Awesome Parts
ES6: The Awesome Parts
Domenic Denicola
 

What's hot (20)

OpenCL 3.0 Reference Guide
OpenCL 3.0 Reference GuideOpenCL 3.0 Reference Guide
OpenCL 3.0 Reference Guide
 
PHP unserialization vulnerabilities: What are we missing?
PHP unserialization vulnerabilities: What are we missing?PHP unserialization vulnerabilities: What are we missing?
PHP unserialization vulnerabilities: What are we missing?
 
Testing in-python-and-pytest-framework
Testing in-python-and-pytest-frameworkTesting in-python-and-pytest-framework
Testing in-python-and-pytest-framework
 
New PHP Exploitation Techniques
New PHP Exploitation TechniquesNew PHP Exploitation Techniques
New PHP Exploitation Techniques
 
Effective testing with pytest
Effective testing with pytestEffective testing with pytest
Effective testing with pytest
 
Understanding .Net Standards, .Net Core & .Net Framework
Understanding .Net Standards, .Net Core & .Net FrameworkUnderstanding .Net Standards, .Net Core & .Net Framework
Understanding .Net Standards, .Net Core & .Net Framework
 
LLVM Register Allocation
LLVM Register AllocationLLVM Register Allocation
LLVM Register Allocation
 
Clean coding-practices
Clean coding-practicesClean coding-practices
Clean coding-practices
 
Typescript ppt
Typescript pptTypescript ppt
Typescript ppt
 
Shootout! Template engines for the JVM
Shootout! Template engines for the JVMShootout! Template engines for the JVM
Shootout! Template engines for the JVM
 
OO Design and Design Patterns in C++
OO Design and Design Patterns in C++ OO Design and Design Patterns in C++
OO Design and Design Patterns in C++
 
The redux saga begins
The redux saga beginsThe redux saga begins
The redux saga begins
 
From object oriented to functional domain modeling
From object oriented to functional domain modelingFrom object oriented to functional domain modeling
From object oriented to functional domain modeling
 
Advanced Object-Oriented/SOLID Principles
Advanced Object-Oriented/SOLID PrinciplesAdvanced Object-Oriented/SOLID Principles
Advanced Object-Oriented/SOLID Principles
 
TypeScript - An Introduction
TypeScript - An IntroductionTypeScript - An Introduction
TypeScript - An Introduction
 
TypeScript
TypeScriptTypeScript
TypeScript
 
Big picture of category theory in scala with deep dive into contravariant and...
Big picture of category theory in scala with deep dive into contravariant and...Big picture of category theory in scala with deep dive into contravariant and...
Big picture of category theory in scala with deep dive into contravariant and...
 
FE로 취업 전에 알았으면 좋았을 것들
FE로 취업 전에 알았으면 좋았을 것들FE로 취업 전에 알았으면 좋았을 것들
FE로 취업 전에 알았으면 좋았을 것들
 
Ruby Programming Language - Introduction
Ruby Programming Language - IntroductionRuby Programming Language - Introduction
Ruby Programming Language - Introduction
 
ES6: The Awesome Parts
ES6: The Awesome PartsES6: The Awesome Parts
ES6: The Awesome Parts
 

Similar to Node.js behind: V8 and its optimizations

Java Performance Tuning
Java Performance TuningJava Performance Tuning
Java Performance Tuning
Atthakorn Chanthong
 
MT_01_unittest_python.pdf
MT_01_unittest_python.pdfMT_01_unittest_python.pdf
MT_01_unittest_python.pdf
Hans Jones
 
E2E testing con nightwatch.js - Drupalcamp Spain 2018
E2E testing con nightwatch.js  - Drupalcamp Spain 2018E2E testing con nightwatch.js  - Drupalcamp Spain 2018
E2E testing con nightwatch.js - Drupalcamp Spain 2018
Salvador Molina (Slv_)
 
Full Stack Unit Testing
Full Stack Unit TestingFull Stack Unit Testing
Full Stack Unit Testing
GlobalLogic Ukraine
 
Ecmascript 2015 – best of new features()
Ecmascript 2015 – best of new features()Ecmascript 2015 – best of new features()
Ecmascript 2015 – best of new features()
Miłosz Sobczak
 
Node Boot Camp
Node Boot CampNode Boot Camp
Node Boot Camp
Troy Miles
 
Node.js System: The Landing
Node.js System: The LandingNode.js System: The Landing
Node.js System: The Landing
Haci Murat Yaman
 
How to fake_properly
How to fake_properlyHow to fake_properly
How to fake_properly
Rainer Schuettengruber
 
Adam Sitnik "State of the .NET Performance"
Adam Sitnik "State of the .NET Performance"Adam Sitnik "State of the .NET Performance"
Adam Sitnik "State of the .NET Performance"
Yulia Tsisyk
 
State of the .Net Performance
State of the .Net PerformanceState of the .Net Performance
State of the .Net Performance
CUSTIS
 
Douglas Crockford: Serversideness
Douglas Crockford: ServersidenessDouglas Crockford: Serversideness
Douglas Crockford: Serversideness
WebExpo
 
vitest-en.pdf
vitest-en.pdfvitest-en.pdf
vitest-en.pdf
ssuser65180a
 
C-Sharp Arithmatic Expression Calculator
C-Sharp Arithmatic Expression CalculatorC-Sharp Arithmatic Expression Calculator
C-Sharp Arithmatic Expression CalculatorNeeraj Kaushik
 
Google App Engine Developer - Day3
Google App Engine Developer - Day3Google App Engine Developer - Day3
Google App Engine Developer - Day3
Simon Su
 
GoFFIng around with Ruby #RubyConfPH
GoFFIng around with Ruby #RubyConfPHGoFFIng around with Ruby #RubyConfPH
GoFFIng around with Ruby #RubyConfPH
Gautam Rege
 
ES6 Overview
ES6 OverviewES6 Overview
ES6 Overview
Bruno Scopelliti
 
Javascript Everywhere
Javascript EverywhereJavascript Everywhere
Javascript Everywhere
Pascal Rettig
 
Unit testing in iOS featuring OCUnit, GHUnit & OCMock
Unit testing in iOS featuring OCUnit, GHUnit & OCMockUnit testing in iOS featuring OCUnit, GHUnit & OCMock
Unit testing in iOS featuring OCUnit, GHUnit & OCMockRobot Media
 
An Introduction to Celery
An Introduction to CeleryAn Introduction to Celery
An Introduction to Celery
Idan Gazit
 
Introduction to web programming for java and c# programmers by @drpicox
Introduction to web programming for java and c# programmers by @drpicoxIntroduction to web programming for java and c# programmers by @drpicox
Introduction to web programming for java and c# programmers by @drpicox
David Rodenas
 

Similar to Node.js behind: V8 and its optimizations (20)

Java Performance Tuning
Java Performance TuningJava Performance Tuning
Java Performance Tuning
 
MT_01_unittest_python.pdf
MT_01_unittest_python.pdfMT_01_unittest_python.pdf
MT_01_unittest_python.pdf
 
E2E testing con nightwatch.js - Drupalcamp Spain 2018
E2E testing con nightwatch.js  - Drupalcamp Spain 2018E2E testing con nightwatch.js  - Drupalcamp Spain 2018
E2E testing con nightwatch.js - Drupalcamp Spain 2018
 
Full Stack Unit Testing
Full Stack Unit TestingFull Stack Unit Testing
Full Stack Unit Testing
 
Ecmascript 2015 – best of new features()
Ecmascript 2015 – best of new features()Ecmascript 2015 – best of new features()
Ecmascript 2015 – best of new features()
 
Node Boot Camp
Node Boot CampNode Boot Camp
Node Boot Camp
 
Node.js System: The Landing
Node.js System: The LandingNode.js System: The Landing
Node.js System: The Landing
 
How to fake_properly
How to fake_properlyHow to fake_properly
How to fake_properly
 
Adam Sitnik "State of the .NET Performance"
Adam Sitnik "State of the .NET Performance"Adam Sitnik "State of the .NET Performance"
Adam Sitnik "State of the .NET Performance"
 
State of the .Net Performance
State of the .Net PerformanceState of the .Net Performance
State of the .Net Performance
 
Douglas Crockford: Serversideness
Douglas Crockford: ServersidenessDouglas Crockford: Serversideness
Douglas Crockford: Serversideness
 
vitest-en.pdf
vitest-en.pdfvitest-en.pdf
vitest-en.pdf
 
C-Sharp Arithmatic Expression Calculator
C-Sharp Arithmatic Expression CalculatorC-Sharp Arithmatic Expression Calculator
C-Sharp Arithmatic Expression Calculator
 
Google App Engine Developer - Day3
Google App Engine Developer - Day3Google App Engine Developer - Day3
Google App Engine Developer - Day3
 
GoFFIng around with Ruby #RubyConfPH
GoFFIng around with Ruby #RubyConfPHGoFFIng around with Ruby #RubyConfPH
GoFFIng around with Ruby #RubyConfPH
 
ES6 Overview
ES6 OverviewES6 Overview
ES6 Overview
 
Javascript Everywhere
Javascript EverywhereJavascript Everywhere
Javascript Everywhere
 
Unit testing in iOS featuring OCUnit, GHUnit & OCMock
Unit testing in iOS featuring OCUnit, GHUnit & OCMockUnit testing in iOS featuring OCUnit, GHUnit & OCMock
Unit testing in iOS featuring OCUnit, GHUnit & OCMock
 
An Introduction to Celery
An Introduction to CeleryAn Introduction to Celery
An Introduction to Celery
 
Introduction to web programming for java and c# programmers by @drpicox
Introduction to web programming for java and c# programmers by @drpicoxIntroduction to web programming for java and c# programmers by @drpicox
Introduction to web programming for java and c# programmers by @drpicox
 

Recently uploaded

NO1 Uk best vashikaran specialist in delhi vashikaran baba near me online vas...
NO1 Uk best vashikaran specialist in delhi vashikaran baba near me online vas...NO1 Uk best vashikaran specialist in delhi vashikaran baba near me online vas...
NO1 Uk best vashikaran specialist in delhi vashikaran baba near me online vas...
Amil Baba Dawood bangali
 
Water Industry Process Automation and Control Monthly - May 2024.pdf
Water Industry Process Automation and Control Monthly - May 2024.pdfWater Industry Process Automation and Control Monthly - May 2024.pdf
Water Industry Process Automation and Control Monthly - May 2024.pdf
Water Industry Process Automation & Control
 
Student information management system project report ii.pdf
Student information management system project report ii.pdfStudent information management system project report ii.pdf
Student information management system project report ii.pdf
Kamal Acharya
 
Nuclear Power Economics and Structuring 2024
Nuclear Power Economics and Structuring 2024Nuclear Power Economics and Structuring 2024
Nuclear Power Economics and Structuring 2024
Massimo Talia
 
Top 10 Oil and Gas Projects in Saudi Arabia 2024.pdf
Top 10 Oil and Gas Projects in Saudi Arabia 2024.pdfTop 10 Oil and Gas Projects in Saudi Arabia 2024.pdf
Top 10 Oil and Gas Projects in Saudi Arabia 2024.pdf
Teleport Manpower Consultant
 
Building Electrical System Design & Installation
Building Electrical System Design & InstallationBuilding Electrical System Design & Installation
Building Electrical System Design & Installation
symbo111
 
一比一原版(UMich毕业证)密歇根大学|安娜堡分校毕业证成绩单专业办理
一比一原版(UMich毕业证)密歇根大学|安娜堡分校毕业证成绩单专业办理一比一原版(UMich毕业证)密歇根大学|安娜堡分校毕业证成绩单专业办理
一比一原版(UMich毕业证)密歇根大学|安娜堡分校毕业证成绩单专业办理
zwunae
 
Unbalanced Three Phase Systems and circuits.pptx
Unbalanced Three Phase Systems and circuits.pptxUnbalanced Three Phase Systems and circuits.pptx
Unbalanced Three Phase Systems and circuits.pptx
ChristineTorrepenida1
 
DESIGN AND ANALYSIS OF A CAR SHOWROOM USING E TABS
DESIGN AND ANALYSIS OF A CAR SHOWROOM USING E TABSDESIGN AND ANALYSIS OF A CAR SHOWROOM USING E TABS
DESIGN AND ANALYSIS OF A CAR SHOWROOM USING E TABS
itech2017
 
Pile Foundation by Venkatesh Taduvai (Sub Geotechnical Engineering II)-conver...
Pile Foundation by Venkatesh Taduvai (Sub Geotechnical Engineering II)-conver...Pile Foundation by Venkatesh Taduvai (Sub Geotechnical Engineering II)-conver...
Pile Foundation by Venkatesh Taduvai (Sub Geotechnical Engineering II)-conver...
AJAYKUMARPUND1
 
Sachpazis:Terzaghi Bearing Capacity Estimation in simple terms with Calculati...
Sachpazis:Terzaghi Bearing Capacity Estimation in simple terms with Calculati...Sachpazis:Terzaghi Bearing Capacity Estimation in simple terms with Calculati...
Sachpazis:Terzaghi Bearing Capacity Estimation in simple terms with Calculati...
Dr.Costas Sachpazis
 
Planning Of Procurement o different goods and services
Planning Of Procurement o different goods and servicesPlanning Of Procurement o different goods and services
Planning Of Procurement o different goods and services
JoytuBarua2
 
DfMAy 2024 - key insights and contributions
DfMAy 2024 - key insights and contributionsDfMAy 2024 - key insights and contributions
DfMAy 2024 - key insights and contributions
gestioneergodomus
 
Design and Analysis of Algorithms-DP,Backtracking,Graphs,B&B
Design and Analysis of Algorithms-DP,Backtracking,Graphs,B&BDesign and Analysis of Algorithms-DP,Backtracking,Graphs,B&B
Design and Analysis of Algorithms-DP,Backtracking,Graphs,B&B
Sreedhar Chowdam
 
digital fundamental by Thomas L.floydl.pdf
digital fundamental by Thomas L.floydl.pdfdigital fundamental by Thomas L.floydl.pdf
digital fundamental by Thomas L.floydl.pdf
drwaing
 
MCQ Soil mechanics questions (Soil shear strength).pdf
MCQ Soil mechanics questions (Soil shear strength).pdfMCQ Soil mechanics questions (Soil shear strength).pdf
MCQ Soil mechanics questions (Soil shear strength).pdf
Osamah Alsalih
 
Tutorial for 16S rRNA Gene Analysis with QIIME2.pdf
Tutorial for 16S rRNA Gene Analysis with QIIME2.pdfTutorial for 16S rRNA Gene Analysis with QIIME2.pdf
Tutorial for 16S rRNA Gene Analysis with QIIME2.pdf
aqil azizi
 
Water billing management system project report.pdf
Water billing management system project report.pdfWater billing management system project report.pdf
Water billing management system project report.pdf
Kamal Acharya
 
Industrial Training at Shahjalal Fertilizer Company Limited (SFCL)
Industrial Training at Shahjalal Fertilizer Company Limited (SFCL)Industrial Training at Shahjalal Fertilizer Company Limited (SFCL)
Industrial Training at Shahjalal Fertilizer Company Limited (SFCL)
MdTanvirMahtab2
 
Hierarchical Digital Twin of a Naval Power System
Hierarchical Digital Twin of a Naval Power SystemHierarchical Digital Twin of a Naval Power System
Hierarchical Digital Twin of a Naval Power System
Kerry Sado
 

Recently uploaded (20)

NO1 Uk best vashikaran specialist in delhi vashikaran baba near me online vas...
NO1 Uk best vashikaran specialist in delhi vashikaran baba near me online vas...NO1 Uk best vashikaran specialist in delhi vashikaran baba near me online vas...
NO1 Uk best vashikaran specialist in delhi vashikaran baba near me online vas...
 
Water Industry Process Automation and Control Monthly - May 2024.pdf
Water Industry Process Automation and Control Monthly - May 2024.pdfWater Industry Process Automation and Control Monthly - May 2024.pdf
Water Industry Process Automation and Control Monthly - May 2024.pdf
 
Student information management system project report ii.pdf
Student information management system project report ii.pdfStudent information management system project report ii.pdf
Student information management system project report ii.pdf
 
Nuclear Power Economics and Structuring 2024
Nuclear Power Economics and Structuring 2024Nuclear Power Economics and Structuring 2024
Nuclear Power Economics and Structuring 2024
 
Top 10 Oil and Gas Projects in Saudi Arabia 2024.pdf
Top 10 Oil and Gas Projects in Saudi Arabia 2024.pdfTop 10 Oil and Gas Projects in Saudi Arabia 2024.pdf
Top 10 Oil and Gas Projects in Saudi Arabia 2024.pdf
 
Building Electrical System Design & Installation
Building Electrical System Design & InstallationBuilding Electrical System Design & Installation
Building Electrical System Design & Installation
 
一比一原版(UMich毕业证)密歇根大学|安娜堡分校毕业证成绩单专业办理
一比一原版(UMich毕业证)密歇根大学|安娜堡分校毕业证成绩单专业办理一比一原版(UMich毕业证)密歇根大学|安娜堡分校毕业证成绩单专业办理
一比一原版(UMich毕业证)密歇根大学|安娜堡分校毕业证成绩单专业办理
 
Unbalanced Three Phase Systems and circuits.pptx
Unbalanced Three Phase Systems and circuits.pptxUnbalanced Three Phase Systems and circuits.pptx
Unbalanced Three Phase Systems and circuits.pptx
 
DESIGN AND ANALYSIS OF A CAR SHOWROOM USING E TABS
DESIGN AND ANALYSIS OF A CAR SHOWROOM USING E TABSDESIGN AND ANALYSIS OF A CAR SHOWROOM USING E TABS
DESIGN AND ANALYSIS OF A CAR SHOWROOM USING E TABS
 
Pile Foundation by Venkatesh Taduvai (Sub Geotechnical Engineering II)-conver...
Pile Foundation by Venkatesh Taduvai (Sub Geotechnical Engineering II)-conver...Pile Foundation by Venkatesh Taduvai (Sub Geotechnical Engineering II)-conver...
Pile Foundation by Venkatesh Taduvai (Sub Geotechnical Engineering II)-conver...
 
Sachpazis:Terzaghi Bearing Capacity Estimation in simple terms with Calculati...
Sachpazis:Terzaghi Bearing Capacity Estimation in simple terms with Calculati...Sachpazis:Terzaghi Bearing Capacity Estimation in simple terms with Calculati...
Sachpazis:Terzaghi Bearing Capacity Estimation in simple terms with Calculati...
 
Planning Of Procurement o different goods and services
Planning Of Procurement o different goods and servicesPlanning Of Procurement o different goods and services
Planning Of Procurement o different goods and services
 
DfMAy 2024 - key insights and contributions
DfMAy 2024 - key insights and contributionsDfMAy 2024 - key insights and contributions
DfMAy 2024 - key insights and contributions
 
Design and Analysis of Algorithms-DP,Backtracking,Graphs,B&B
Design and Analysis of Algorithms-DP,Backtracking,Graphs,B&BDesign and Analysis of Algorithms-DP,Backtracking,Graphs,B&B
Design and Analysis of Algorithms-DP,Backtracking,Graphs,B&B
 
digital fundamental by Thomas L.floydl.pdf
digital fundamental by Thomas L.floydl.pdfdigital fundamental by Thomas L.floydl.pdf
digital fundamental by Thomas L.floydl.pdf
 
MCQ Soil mechanics questions (Soil shear strength).pdf
MCQ Soil mechanics questions (Soil shear strength).pdfMCQ Soil mechanics questions (Soil shear strength).pdf
MCQ Soil mechanics questions (Soil shear strength).pdf
 
Tutorial for 16S rRNA Gene Analysis with QIIME2.pdf
Tutorial for 16S rRNA Gene Analysis with QIIME2.pdfTutorial for 16S rRNA Gene Analysis with QIIME2.pdf
Tutorial for 16S rRNA Gene Analysis with QIIME2.pdf
 
Water billing management system project report.pdf
Water billing management system project report.pdfWater billing management system project report.pdf
Water billing management system project report.pdf
 
Industrial Training at Shahjalal Fertilizer Company Limited (SFCL)
Industrial Training at Shahjalal Fertilizer Company Limited (SFCL)Industrial Training at Shahjalal Fertilizer Company Limited (SFCL)
Industrial Training at Shahjalal Fertilizer Company Limited (SFCL)
 
Hierarchical Digital Twin of a Naval Power System
Hierarchical Digital Twin of a Naval Power SystemHierarchical Digital Twin of a Naval Power System
Hierarchical Digital Twin of a Naval Power System
 

Node.js behind: V8 and its optimizations

  • 1. Node.js behind: V8 engine & its optimizations
  • 2. Agenda • What is V8? • Full-codegen • Crankshaft • TurboFan • Ignition • Optimizations & memory representation by examples • Garbage collector & memory leaks • Useful links
  • 4. 2010 Introduced Crankshaft 2014 Introduced TurboFan 2016 Introduced Ignition 2015 TurboFan enabled in Chrome 41 2017 Ignition in Chrome 58 for tests 2008 Introduced V8 2009 Introduced Node.js …
  • 5. Compiler pipeline What is V8? Source Bytecode Unoptimized code Optimized code Parser Ignition Parser Full-codegen Crankshaft TurboFan Parser Deoptimize Interpreted Baseline Optimized
  • 6. Desired compiler pipeline What is V8? Source Bytecode Optimized code Parser Ignition TurboFan Deoptimize Interpreted Optimized
  • 8. How full-codegen works? • Compiles JS code directly to native code before executing it • Needs to compile code as quick as possible • It’s not optimizing code • One function at a time, compiling just in time • Uses Inline Caches to implement loads, stores calls, binary, unary and comparison • Implementation of IC is stub, generated on the fly, can be cached for common cases • Stub on beginning has no instructions, each missed call makes it more complicated Full-codegen
  • 10. How Crankshaft works? • Only selected "hot" functions are passed for optimizations. • Hot: marked for optimization -> LazyRecompile -> optimizing • Hot: uninitialized -> premonomorphic -> monomorphic • Most of time will mark to optimize at second call • Sometimes compiler will optimize it immediately (big loops) - on-stack replacement • Builds Hydrogen control flow graph (SSA) • Optimizes in Hydrogen graph (only part which can be in parallel to JS) • Generates Lithium graph • Emit native instructions Crankshaft
  • 11. Static single assignment form Crankshaft From: https://en.wikipedia.org/wiki/Static_single_assignment_form x ← 5 x ← x - 3 x<3? y ← x * 2 w ←y y ← x - 3 w ← x - y z ←x + y x1 ← 5 x2 ← x - 3 x2<3? y1 ← x2 * 2 w1 ← y1 y2 ← x2 - 3 w2 ← x2 - y? z1 ←x2 + y?
  • 12. Static single assignment form Crankshaft From: https://en.wikipedia.org/wiki/Static_single_assignment_form x ← 5 x ← x - 3 x<3? y ← x * 2 w ←y y ← x - 3 w ← x - y z ←x + y x1 ← 5 x2 ← x - 3 x2<3? y1 ← x2 * 2 w1 ← y1 y2 ← x2 - 3 y3 = Φ(y1,y2) w2 ← x2 - y3 z1 ←x2 + y3
  • 13. What is Crankshaft optimizing? • Inline functions - when it’s safe and they are small • Tag values - e.g. integer, double • Analyze Uint32 - by default uses 31-bit for small signed integers, allow use of bigger • Canonicalization - simplify • Global Value Numbering (GVN) - eliminate redundancy • Redundant bounds check elimination - remove unneeded checks for arrays • Dead code elimination Crankshaft
  • 15. How TurboFan works? • Uses „sea of nodes” concept • Can work directly on byte code (works perfectly with Ignition) • Machine code is emitted • Able to easily handle more features (e.g. from ES6) • More aggressive than Crankshaft • Optimizes progressively • Has scheduling algorithm TurboFan
  • 17. How to enable Ignition? • In Chrome it’s put on A/B tests or you can use flag disable-v8-ignition-turbo • In Node.js 7+ use --ignition flag Ignition
  • 18. How Ignition works? • It’s interpreter • Compiles to byte code • Reduce memory usage for compiling (important for mobile) • Improve startup time • Simplify compilation pipeline • Perform some optimizations, e.g. remove dead-code Ignition
  • 19. Optimizations & memory representation by examples
  • 20. How tests were prepared? • MacBook Pro (early 2015), i5 2.7GHz, 8GB DDR3 • Node.js 7.7.1 (V8 5.5.372.41) • Time calculated by time node script.js • Number of iterations vary in test cases Optimizations & memory representation by examples
  • 21. Try/catch // Set up number of iterations const iterations = 1e9 // Set up function for tests function f () { return 1 + 2 * 3 / 4 } // Set up function which calls function function test () { for (var i = 0; i < iterations; i++) { f(i) } } try { test() } catch (e) { // Do nothing } real: 0.663s user: 0.555s sys: 0.027s Optimizations & memory representation by examples // Set up number of iterations const iterations = 1e9 // Set up function for tests function f () { return 1 + 2 * 3 / 4 } // Set up function which calls function function test () { try { for (var i = 0; i < iterations; i++) { f(i) } } catch (e) { // Do nothing } } test() real: 8.826s user: 8.496s sys: 0.071s
  • 22. Try/catch // Set up number of iterations const iterations = 1e9 // Set up function for tests function f () { return 1 + 2 * 3 / 4 } // Set up function which calls function function test () { for (var i = 0; i < iterations; i++) { f(i) } } try { test() } catch (e) { // Do something } real: 0.663s user: 0.555s sys: 0.027s Optimizations & memory representation by examples // Set up number of iterations const iterations = 1e9 // Set up function for tests function f () { return 1 + 2 * 3 / 4 } // Set up function which calls function function test () { try { for (var i = 0; i < iterations; i++) { f(i) } } catch (e) { // Do something } } test() real: 8.826s user: 8.496s sys: 0.071s
  • 23. For..in // Set up number of iterations const iterations = 1e8 // Set up function for tests function f () { var obj = {} var key for (key in obj) { // Do nothing } } // Benchmark function for (var i = 0; i < iterations; i++) { f(1, 2, 3, 4, 5) } real: 1.416s user: 1.281s sys: 0.042s // Set up number of iterations const iterations = 1e8 // Set up function for tests var key function f () { var obj = {} for (key in obj) { // Do nothing } } // Benchmark function for (var i = 0; i < iterations; i++) { f(1, 2, 3, 4, 5) } real: 3.181s user: 2.868s sys: 0.055s Optimizations & memory representation by examples
  • 24. For..in // Set up number of iterations const iterations = 1e8 // Set up function for tests function f () { var obj = {} var key for (key in obj) { // Do nothing } } // Benchmark function for (var i = 0; i < iterations; i++) { f(1, 2, 3, 4, 5) } real: 1.416s user: 1.281s sys: 0.042s // Set up number of iterations const iterations = 1e8 // Set up function for tests var key function f () { var obj = {} for (key in obj) { // Do nothing } } // Benchmark function for (var i = 0; i < iterations; i++) { f(1, 2, 3, 4, 5) } real: 3.181s user: 2.868s sys: 0.055s Optimizations & memory representation by examples
  • 25. for..of vs classic for loop // Set up number of iterations const iterations = 1e8 // Set up data const arr = [ 0, 1, 2, 3, 4 ] // Set up function for tests function f () { for (var element of arr) { // Do nothing } } // Benchmark function for (var i = 0; i < iterations; i++) { f() } real: 13.879s user: 13.662s sys: 0.099s // Set up number of iterations const iterations = 1e8 // Set up data const arr = [ 0, 1, 2, 3, 4 ] // Set up function for tests function f () { for (var i = 0; i < arr.length; i++) { var el = arr[i] } } // Benchmark function for (var i = 0; i < iterations; i++) { f() } real: 0.722s user: 0.620s sys: 0.028s Optimizations & memory representation by examples
  • 26. for..of implementation class Iterable { constructor (...elements) { this.els = elements || [] } add (...elements) { this.els.push(...elements) } *[Symbol.iterator] () { yield* this.els } } const a = new Iterable(1, 2, 3, 4) for (let element of a) { console.log(element) } class Iterable2 { constructor (...elements) { this.els = elements || [] } add (...elements) { this.els.push(...elements) } *[Symbol.iterator] () { for (let i = 0; i < this.els.length; i++) { yield this.els[i] } } } Optimizations & memory representation by examples
  • 27. Mono & polymorphic operations // Set up number of iterations const iterations = 1e9 // Set up function for tests function f (x) { return x + 'a' } // Set up testing values const values = [ 0, 1, 2, 3, 4, 5 ] const length = values.length // Benchmark function for (var i = 0; i < iterations; i++) { var value = values[i % length] f(value) } real: 7.325s user: 6.697s sys: 0.071s // Set up number of iterations const iterations = 1e9 // Set up function for tests function f (x) { return x + 'a' } // Warm function with different types of values f(undefined), f(null), f('a'), f(true) // Set up testing values const values = [ 0, 1, 2, 3, 4, 5 ] const length = values.length // Benchmark function for (var i = 0; i < iterations; i++) { var value = values[i % length] f(value) } real: 21.012s user: 20.271s sys: 0.159s Optimizations & memory representation by examples
  • 28. Mono & polymorphic operations // Set up number of iterations const iterations = 1e9 // Set up function for tests function f (x) { return x + 'a' } // Set up testing values const values = [ 0, 1, 2, 3, 4, 5 ] const length = values.length // Benchmark function for (var i = 0; i < iterations; i++) { var value = values[i % length] f(value) } real: 7.325s user: 6.697s sys: 0.071s // Set up number of iterations const iterations = 1e9 // Set up function for tests function f (x) { return x + 'a' } // Warm function with different types of values f(undefined), f(null), f('a'), f(true) // Set up testing values const values = [ 0, 1, 2, 3, 4, 5 ] const length = values.length // Benchmark function for (var i = 0; i < iterations; i++) { var value = values[i % length] f(value) } real: 21.012s user: 20.271s sys: 0.159s Optimizations & memory representation by examples
  • 29. Mono & polymorphic operations• Different types causes different native operations • Monomorphic stub has only one case • Megamorphic stub has more cases • For different cases needs to cover „safety gates” to handle different types Optimizations & memory representation by examples
  • 30. Objects interpretation // Set up number of iterations const iterations = 1e9 const obj = { 0: 1 } // Set up function for tests function f (i) { obj[0] = i } // Benchmark function for (var i = 0; i < iterations; i++) { f(i) } real: 0.837s user: 0.729s sys: 0.030s // Set up number of iterations const iterations = 1e9 const obj = { x: 1 } // Set up function for tests function f (i) { obj.x = i } // Benchmark function for (var i = 0; i < iterations; i++) { f(i) } real: 0.579s user: 0.554s sys: 0.013s Optimizations & memory representation by examples
  • 31. Object representation in memory• Hash tables (dictionaries) - used for difficult objects, slow • Fast elements - object with integer indexes, handled differently (can be array), small • Fast, in-object properties - create hidden classes, shared same structure (transitions) • Methods & Prototypes - Functions go as constant_function to map • Object can move from one representation to another Optimizations & memory representation by examples
  • 32. Hidden classes Optimizations & memory representation by examples function Point (x, y) { // Map M0 // ”x”: Transition to M1 at offset 12 this.x = x // Map M1 // ”x” at 12 // ”y”: Transition to M2 at offset 16 this.y = y // Map M2 // ”x” at 12, ”y” at 16 // ”do”: Transition to M3 <doSomething> this.do = doSomething // Map M3 // ”x” at 12, ”y” at 16 // ”do”: Constant_Function <doSomething> } function doSomething (p) { /* ……… */ } From: https://github.com/thlorenz/v8-perf function Point (x, y) { this.x = x this.y = y if (x > 10) { this.big = true } } // Map X const a = new Point(5, 0) // Map Y const b = new Point(20, 0)
  • 33. Hidden classes Optimizations & memory representation by examples function Point (x, y) { // Map M0 // ”x”: Transition to M1 at offset 12 this.x = x // Map M1 // ”x” at 12 // ”y”: Transition to M2 at offset 16 this.y = y // Map M2 // ”x” at 12, ”y” at 16 // ”do”: Transition to M3 <doSomething> this.do = doSomething // Map M3 // ”x” at 12, ”y” at 16 // ”do”: Constant_Function <doSomething> } function doSomething (p) { /* ……… */ } From: https://github.com/thlorenz/v8-perf function Point (x, y) { // Map M0 this.x = x // Map M1 this.y = y // Map M2 if (x > 10) { this.big = true // Map M3 } } // Map M2 const a = new Point(5, 0) // Map M3 const b = new Point(20, 0)
  • 34. Object representation Optimizations & memory representation by examples
  • 35. Determine type of variable // Set up number of iterations const iterations = 1e8 // Set up function for tests function f () { var attr = arguments if (1 === 1) { attr = [ 0 ] } } // Benchmark function for (var i = 0; i < iterations; i++) { f(i) } // Set up number of iterations const iterations = 1e8 // Set up function for tests function f () { var attr = arguments var x = [ 1 ] if (1 === 1) { x = [ 0 ] } } // Benchmark function for (var i = 0; i < iterations; i++) { f(i) } real: 3.696s user: 3.466s sys: 0.064s real: 1.679s user: 1.454s sys: 0.037s Optimizations & memory representation by examples
  • 36. Mutate arguments // Set up number of iterations const iterations = 1e9 // Set up function for tests function f () { // Modify arguments element arguments[0] = 0 return arguments[0] } // Benchmark function for (var i = 0; i < iterations; i++) { f(1) } real: 31.372s user: 31.064s sys: 0.106s // Set up number of iterations const iterations = 1e9 // Set up array-like object to modify property var dummy = { 0: 1, length: 1 } // Set up function for tests function f () { // Modify dummy element dummy[0] = 0 return arguments[0] } // Benchmark function for (var i = 0; i < iterations; i++) { f(1) } real: 1.854s user: 1.753s sys: 0.029s Optimizations & memory representation by examples
  • 37. Mutate arguments // Set up number of iterations const iterations = 1e9 // Set up function for tests function f () { // Modify arguments element arguments[0] = 0 return arguments[0] } // Benchmark function for (var i = 0; i < iterations; i++) { f(1) } real: 31.372s user: 31.064s sys: 0.106s // Set up number of iterations const iterations = 1e9 // Set up array-like object to modify property var dummy = { 0: 1, length: 1 } // Set up function for tests function f () { // Modify dummy element dummy[0] = 0 return arguments[0] } // Benchmark function for (var i = 0; i < iterations; i++) { f(1) } real: 1.854s user: 1.753s sys: 0.029s Optimizations & memory representation by examples
  • 38. Mutate arguments variables // Set up number of iterations const iterations = 1e9 // Set up function for tests function f (arg) { // Modify argument arg = 0 return arguments[0] } // Benchmark function for (var i = 0; i < iterations; i++) { f(1) } real: 31.570s user: 31.233s sys: 0.128s // Set up number of iterations const iterations = 1e9 // Set up function for tests function f (arg) { // Modify argument arg = 0 return arg } // Benchmark function for (var i = 0; i < iterations; i++) { f(1) } real: 0.699s user: 0.554s sys: 0.036s Optimizations & memory representation by examples
  • 39. Methods to find bottlenecks Optimizations & memory representation by examples • Find problems by profiler / timeline (e.g. Chrome DevTools) • Since 6.3: node —inspect-brk: Inspect code with DevTools • node —trace-opt: trace optimizations on functions • node —trace-deopt: trace deoptimizations • node —allow-natives-syntax: Native Syntax for advanced scripting with V8 access • node —prof: Profile code, generates v8.log file • node —prof-process v8.log
  • 40. Profiling Node (isolate-xxx-v8.log) Optimizations & memory representation by examples [Shared libraries]: ticks total nonlib name 9 0.2% 0.0% C:WINDOWSsystem32ntdll.dll 2 0.0% 0.0% C:WINDOWSsystem32kernel32.dll [JavaScript]: ticks total nonlib name 741 17.7% 17.7% LazyCompile: am3 crypto.js:108 113 2.7% 2.7% LazyCompile: Scheduler.schedule richards.js:188 103 2.5% 2.5% LazyCompile: rewrite_nboyer earley-boyer.js:3604 103 2.5% 2.5% LazyCompile: TaskControlBlock.run richards.js:324 96 2.3% 2.3% Builtin: JSConstructCall ... [C++]: ticks total nonlib name 94 2.2% 2.2% v8::internal::ScavengeVisitor::VisitPointers 33 0.8% 0.8% v8::internal::SweepSpace 32 0.8% 0.8% v8::internal::Heap::MigrateObject 30 0.7% 0.7% v8::internal::Heap::AllocateArgumentsObject ... [GC]: ticks total nonlib name 458 10.9%
  • 42. What is Garbage Collector for? • Delete data from memory when it’s no longer needed • Garbage collector most of time may be slower than managing memory by self • Program has to stop while garbage collector is working • Make easier for developer to manage memory Garbage collector & memory leaks
  • 43. How does GC work? • There is created tree of nodes (with dependencies) • Everything what is accessible from root (all global objects, all in branches) is live • New data is most of time temporary, so probably should be earlier destroyed Garbage collector & memory leaks
  • 44. Memory zones & collecting garbage• Young generation = New space, Old generation = Old space • After surviving for a while in new space, elements are moved to old space • Allocation to old space is fast, but collecting there is slower • On new space - scavenge collection, old - mark-sweep (or mark-compact) • Marking can be processed in chunks • There are 3 marking states: • White - object not discovered by GC • Grey - discovered, but not all neighbors processed • Black - all of neighbors has been fully processed Garbage collector & memory leaks
  • 45. Collecting garbage Garbage collector & memory leaks root a b c d
  • 46. Collecting garbage Garbage collector & memory leaks a b c d root
  • 47. Collecting garbage Garbage collector & memory leaks d root a b c
  • 48. Collecting garbage Garbage collector & memory leaks root a b c d // Remove pointer from 'a' to 'd' a.property = null
  • 49. Collecting garbage Garbage collector & memory leaks a b c root // Remove pointer from 'a' to 'd' a.property = null d
  • 50. Collecting garbage Garbage collector & memory leaks root // Remove pointer from 'a' to 'd' a.property = null a b c d
  • 51. Collecting garbage Garbage collector & memory leaks a b c root // Remove pointer from 'a' to 'd' a.property = null
  • 52. Memory zones • New space - garbage collected quickly, 1-8MB space • Old pointer space - objects which have pointers to other, moving from „new” after while • Old data space - objects which contain raw data (objects, strings, arrays etc) • Large object space - objects larger than size limit for other spaces, never moved • Code space - JITed instructions, code objects • Cell space, map space, property cell space - Cells, PropertyCells and Maps Garbage collector & memory leaks
  • 53. Memory leaks: examples Garbage collector & memory leaks function f () { obj = { a: 1, b: 1 } } • It might be by accident • It assigns to this element • this may be global or window • Assigned to root, so will not be removed
  • 54. Memory leaks: examples Garbage collector & memory leaks // Get some data var r = getData() // Process data function process () { if (shouldProcess()) { console.log(r.items) } } // Do something in interval setInterval(process, 10000) • Intervals which uses some data • When they are not needed - clear them
  • 55. Memory leaks: examples Garbage collector & memory leaks var theThing = null function replaceThing () { var originalThing = theThing var unused = function () { if (originalThing) { console.log("hi") } } theThing = { longStr: new Array(1000000).join('*'), someMethod: function () { console.log(someMessage) } } } setInterval(replaceThing, 1000) • Closures can be bad • unused keeps pointer to originalThing • someMethod share closure with unused • Keeps reference to old theThing
  • 56. Memory leaks: how to detect Garbage collector & memory leaks • Generate heap dumps (record in Chrome, or e.g. use `heapdump` module) • Chrome DevTools - JS Profiler: Comparison • Compare two/three snapshots from different time - you will see what is left From: http://bit.ly/2pcDTe9
  • 57. Memory leaks: how to detect Garbage collector & memory leaks • Generate heap dumps (record in Chrome, or e.g. use `heapdump` module) • Chrome DevTools - JS Profiler: Comparison • Compare two/three snapshots from different time - you will see what is left • Other way: use GCore gcore `pgrep node` > ::findjsobjects object_id::jsprint object_id::findjsobjects -r
  • 59. Useful links • https://github.com/v8/v8 - V8 code mirror on GitHub • https://v8project.blogspot.com/ - Blog with V8 insights • http://v8-io12.appspot.com/ - V8 overview (2012) • http://bit.ly/2oBGvht - Ignition presentation (2016) • http://bit.ly/2p68bgf - measure and optimize GC for RAIL (2016) • http://bit.ly/2q4fsfS - RisingStack article, pretty simple about GC (2016) • http://bit.ly/2oBDXjk - Jay Conrod wrote series about V8 mechanisms (2012) • http://darksi.de/d.sea-of-nodes/ - Sea of node explanation • https://github.com/thlorenz/v8-perf/ - Some stuff about V8 (2014)
  • 60. Thanks for attention! Something more? Catch me at drusnak@g2a.com Find presentation at: https://bit.ly/node-js-behind

Editor's Notes

  1. Not contributor, digging deeper is essential for programmers. When junior looks at code, he may not see something, but mid/senior dig little deeper. Also you can encounter analogies between it and other tools/things.
  2. Tell you about V8 itself, its components: /list them/, how does it work and how it affects your code. We’ve got 45 minutes, I’ll just try to show most important stuff and encourage you to read little more about that. Presentation is available on the web, so you can even look at it later.
  3. V8 is JavaScript engine which executes your code. It’s open-source & mostly maintained by Google. It’s used widely, e.g. Chrome, Node.js, Opera or Vivaldi.
  4. V8 started at 2008, being fastest JS engine. Meanwhile all other engines was trying to beat it. In 2009 Node.js based on V8 was introduced. It shown that JS can be used also server-side. In 2010 was introduced 1st optimizing compiler, but have some design issues. Web has become more complicated, so to fix problems with Crankshaft and optimize code in case of asm.js in 2014 V8 team shown TurboFan, 2nd optimizing compiler. It is much more flexible, has been enabled in Chrome in 2015. In 2016 there was a need to decrease memory for compiling, so Ignition was a resolution for that. 2008 - 2 September 2009 - ? 2010 - 7 December 2014 - ? 2015 - ? 2016 - July 2017 - January/February 2017 goal - get rid of Crankshaft and Full-codegen
  5. Looks a little complicated. Three almost independent parts now. Only AST can be reused between. 3 JITs and one interpreter.
  6. In 2017 pipeline will be simplified. TurboFan can use bytecode directly, Source -> Parser -> AST -> Ignition -> Bytecode -> Turbofan -> Optimized code
  7. It’s simply translating JS to native code. It has to be fast, to deliver execution asap. Because of that, it’s not optimizing. JIT compiler, so compiles function just when it’s needed. Operations can be inlined with inline caches. Implementation of IC is stub. It caches operations needed to perform for specific cases. Later I will show you example how it affects you.
  8. It’s JIT. Optimizes hot functions. uninitialized > marked for optimization > optimized (with monomorphic stub) > polymorphic. Most of time mark 2nd call. On-stack replacement - immediately. Uses 2 representations: Hydrogen & Lithium. Most optimizations in hydrogen. hydrogen -> lithium -> native instructions. SSA - Static Single Assignment form. Hot: earlier it was checking each 1 or 5ms and if seen function several times marked as hot
  9. Always assigning to new variable. Determine by Φ (Phi) which variable should be taken according to branches where algorithm gets in.
  10. Always assigning to new variable. Determine by Φ (Phi) which variable should be taken according to branches where algorithm gets in.
  11. Optimizations: - dynamic type feedback: get information from full-compiler about inline caches (optimizes e.g. for going to key => value) inlining: when it’s safe, function will be inlined (not large functions, not dangerous Representation inference: tag values (most important for numbers: raw integer - fastest, double) static type inference: match type of function (not possible most time, because only one function) Uint32 analysis: JS uses only 31-bit for small signed integers, marks some types as unsigned to allow bigger canonicalization: just simplify operations Global value numbering (GVN): eliminate redundancy - hashes for opcodes and remove them Loop invariant code motion (LICM): if function in loop doesn’t use loop context, put it to pre-header Redundant bounds check elimination: remove unneeded checks for arrays Array index dehoisting: revert LICM for some operations (n++, n += 20) Dead code elimination
  12. „Sea of nodes” - easier to optimize. not ordering nodes except participating in control flow. change any part of execution. Can work on byte code (Ignition), more aggressive. Uses optimization layers. Layers allow easier handling new features. Can work in parallel increasing optimization.
  13. Ignition is right now in tests phase. As before - in 2017 it will be used widely deprecating Crankshaft and Full-codegen. In Chrome use flag in chrome://flags, in Node use —ignition.
  14. It’s byte code interpreter. Reduces memory usage, simplifies pipeline working with TurboFan. Executes byte code very properly on real-world websites. Additionally startup should be faster. Also has mechanisms for optimizations, e.g. remove dead code. Right now it’s not working fully as expected, is little slower.
  15. Number vary because sometimes I just didn’t want to wait hour for tests.
  16. Many people see try/catch as slow. Compiler when see try/catch can’t optimize - try/catch is too hard because of various cases.
  17. But looking at another code we get more almost 15 times faster. When we put it out of processing function, then processing can be optimized.
  18. Next, less obvious example - we’ve got simple for in loop on some object. We want to try to optimize it - 100kk times we are declaring key, put it outside!
  19. No, it’s slower. I haven’t found a reason for that, but when key variable is out of closure, loop is not optimized. Probably because loop invariant code motion (LICM). It’s not obvious.
  20. Very practical, had this many times. Compiler throw ForOfStatement as reason for not optimizing. For..of has much more behind. Let look at it inside.
  21. There is a lot of reasons shown by compiler for not optimizing, but lot of them based on some core problems. In this case we’ve got generators which are not optimizable yet.
  22. We’ve got here simple function which runs billion times, returning concatenated number with string. Make some small difference.
  23. Now we are running function billion + 4 times, getting 3x increased time. That’s because of stubs which I said about before.
  24. So, for each operation compiler tries to inline how it should work. When we have only one case it’s called monomorphic stub, more - mega. Megamorphic stubs must be slower, as they need to cover more safety gates - strings are handled differently than numbers etc.
  25. We’ve got here two examples which are just attaching values to one of properties. So why there is a difference in time?
  26. There are different methods of representing object in memory. Hash tables - difficult objects, slow. Fast elements - objects with integer indexes, but small (<100k elements). In-object properties - creates hidden classes, are based on transitions. Methods are treat differently to optimize frequent situation. Important is that objects can move from one representation to another - e.g. when you remove some index in array it might be used as hash table.
  27. We have to see how exactly hidden classes works. Each time property is assigned, there is another hidden class created.
  28. Here we’ve got example in more common code - we’ve got one conditional in constructor, and 2 instances of Point. In memory they will not share some structure - first will be M2, second M3, as conditional result is different.
  29. In Map hidden class structure, properties on end are in-object properties, extra properties are hash map properties and elements are properties for fast elements objects.
  30. Another example of types - compiler can’t determine what type arguments is, so when you try to change value of this variable, it takes more time.
  31. Last example - mutating arguments. As you know, arguments is magic variable in functions. It needs to be always aligned to named arguments. It causes yet problems for compiler, as it has to align it properly.
  32. As comparison, let see some function which is mutating similar (array-like) object. It’s more than 15 times faster.
  33. Anyway, if you want to mutate arguments, let see on other options. When we mutate named argument but read arguments object it’s still slow, but when we use only named we get proper speed. Deduction: more magic = more problems
  34. in Chrome DevTools most important - use timeline & profiler (it will show also not optimized functions), in case of Node we’ve got many additional options, some helpful: inspect, trace-opt & trace-deopt (trace (de)optimizations), allow-natives-syntax which allow advanced scripting, —prof for profiling and —prof-process for reading log from this
  35. That’s how looks log in node —prof-process, so you can see where to find problems; you can see there also external modules (e.g. C++)
  36. Garbage Collector is a component which is responsible for deleting data from memory when they’re not needed. In V8 there is using Tracing garbage collector algorithm. Managing memory by yourself must be more efficient, but with GC you don’t have to think about it much. GC in V8 has stop-the-world mechanism.
  37. Garbage collector makes graph of nodes with pointers between. All objects which are accessible from root (e.g. global or window) are live. It’s safe to make assumption that most new data are temporary, so should be earlier destroyed (e.g. counters in loop).
  38. 2 generations: young and old. When object is surviving in new space for a while it’s moved to old space. Allocation to old is fast, collecting not. New space (as said before) most of time uses temp, so it’s cleared faster, old uses slow algorithm. It’s marking objects if they are live, and sweep dead ones. Right now, marking can be processed in chunks.
  39. Let show simplified example of collection. We start from root object and go to all its child nodes.
  40. We checked B and it hasn’t any child nodes, but it’s reachable - mark it as black. A has nodes.
  41. Now we’ve checked all nodes. Time to collect.
  42. We are removing pointer from A to D which is stored in A.property.
  43. As before we go from root to child nodes
  44. Now we passed whole tree, where D had no pointers.
  45. So D is swept from memory. It’s ofc simplified - in truth there are still pointers to this element till now and when we reach A pointer is removed.
  46. New space is pretty simple, but there are other spaces in memory. We’ve got code space - code & instructions are stored, spaces like cell, map or property cell space where we store information needed for compiler job, old space splitted to 3 parts - pointer space (objects with pointers, data - raw data, large object - big objects which can’t be stored anyway is stored there.
  47. I will tell you some common memory leaks. You could assign to global values (under root), which might be big.
  48. Another: Timers which use some external data. You should clear it. Also applies to e.g. listeners or cached DOM elements.
  49. More complex example. Similar happened in Meteor framework. We’ve got a function which is replacing old data with new, but using old one. There is one unused function and someMethod. Problem is that functions in same closure share it. Unused -> originalThing (which is old one), someMethod keeps referencing all the time. Because of that, each interval all stuff (with longStr) is leaked.
  50. And now: how to detect leaks. In Chrome you can use just Profiler in DevTools, in NodeJS you can use heapdump module to dump heap. You can also import it in DevTools. Compare two or more snapshots and see difference by Comparison type.
  51. Less often stuff - you can use general GCore program (linux). You can more programmatically search for stuff in memory by this tool.
  52. Response, Animation, Idle, Load