Work with V8 memory leaks

27
Work with leaks Roman Krivtsov

Transcript of Work with V8 memory leaks

Work with leaks Roman Krivtsov

Leaks in js:Easy to create (timers, closures, listeners)

Difficult to find out

Critical in long-live apps

2

3

Gmail with leaks

3:00

4

Server programmer’s life

V8 GARBAGE COLLECTOR

5

— Concept of reachability— Blocked event-loop— Totally optimising

(partions, dynamic intervals)— New space (1-8Mb)

& Old space (512Mb-1.7Gb)

6

GC

— max-old-space-size limit for old-space GC

— nouse-idle-notification prevent running GC constantly

— expose-gc global.gc()

— trace-gc logging

— trace-gc-verbose extended logging

Flags

7

8

PATTERNS AND ANTIPATTERNS

var latestNews = function (html) { var container = document.getElementById("news"); container.innerHTML = html; container.addEventListener("click", function click() { showFullItem(); }); } setInterval(XHR.bind(null, "/get_news", latestNews), 1000);

9

Latest news

10

container

DOM

Window

click listener click listenerclick listener

click listenerclick listener

12

var latestNews = function (html) { var container = document.getElementById("news"); container.innerHTML = html; container.addEventListener("click", function click() { showFullItem(html); }); } setInterval(XHR.bind(null, "/get_news", latestNews), 1000);

Variable usage

13

14

Scopes

clickhtml

latestNews html

clickhtmlclickhtml

clickhtml

15

var latestNews = function (html) { var container = document.getElementById("news"); container.innerHTML = html; container.addEventListener("click", function click() { showFullItem(); });

var unused = function () { if (html) console.log("never"); }} setInterval(XHR.bind(null, "/get_news", latestNews), 1000);

Deeper down the rabbit hole

16

17

Scopes

click

latestNews html

unusedhtmlhtml =

18

var latestNews = function (html) { var container = document.getElementById("news"); container.innerHTML = html; html = null; container.addEventListener("click", function click() { showFullItem(html); }); } setInterval(XHR.bind(null, "/get_news", latestNews), 1000);

var job = function () { mysql.query("select * from tasks order by ts desc", function (err, res) { use(res); }); } setInterval(job, 1000);

19

Long responses

mysql.query({ sql: 'select * from tasks order by ts', timeout: 1000});

TOOLS

20

Events CPU

Memory

Force GC

Timeline

Rule of 3 snapshots

Profiling

Retained sizeShallow sizeDistance

— node-heapdump— node-memwatch— REPL— dynamic tracing frameworks

23

Node.js

--abort-on-uncaught-exception

24

— production

MDB and DTrace(dynamic tracing frameworks)

— Timers— Frequent events— Listeners— Parent scope— Give names— Clear big variables— Databases

Conclusions

25

Good luckand don’t leak!

26

27

Code and links