翻蚳è
ããïŒããã¯ã ãã«ãœããããžã§ã¯ãã«é¢äžããMozilla IdentityããŒã ã«ããNode.jsã·ãªãŒãºã®æåã®èšäºã§ãã ãã«ãœãã®ã¯ã©ã€ã¢ã³ãåŽãšãµãŒããŒåŽã®äž¡æ¹ãJavaScriptã§èšè¿°ãããŠããŸãã äœæ¥ã®éçšã§ããããžã§ã¯ãããŒã ã¯ãããŒã«ã©ã€ãºãããããã°ãäŸåé¢ä¿ç®¡çãªã©ãããããå Žé¢ã§ããã€ãã®ããŒã«ãäœæããŸããã ãã®äžé£ã®èšäºã§ã¯ãMozillaéçºè
ãã³ãã¥ããã£ãNode.jsã§è² è·ã®é«ããµãŒãã¹ãäœæãã人ã«ãšã£ãŠåœ¹ç«ã€ãããã®ããŒã«ãšçµéšãå
±æããŠããŸãã
ã·ãªãŒãºã®æåã®èšäºã¯ãNode.jsã®äžè¬çãªåé¡-ã¡ã¢ãªãªãŒã¯ãé«è² è·ãããžã§ã¯ãã®ãªãŒã¯æ©èœãããã³Nodeã§ãã®ãããªãªãŒã¯ãèŠã€ããŠä¿®æ£ããã®ã«åœ¹ç«ã€node-memwatchã©ã€ãã©ãªã«çŠç¹ãåœãŠãŠããŸãã
ãµã€ã¯ã«ã®ãã¹ãŠã®èšäºïŒ
ãªãããããïŒ
ãªãã¡ã¢ãªãªãŒã¯ãç£èŠããã®ã§ããããïŒ ãã£ãšéèŠãªããšã¯ãããŸããïŒ ããã»ã¹ãæã
åèµ·åãããããµãŒããŒã«ã¡ã¢ãªãè¿œå ãããããªãã®ã¯ãªãã§ããïŒ æŒãããªããããšãäŸç¶ãšããŠéèŠã§ããçç±ã¯3ã€ãããŸãã
- ã¡ã¢ãªãªãŒã¯ã«ã€ããŠããŸãå¿é
ããããšã¯ãªããããããŸããããV8ïŒNodeãå®è¡ãããJavaScriptãšã³ãžã³ïŒã«ã€ããŠã¯èšããŸããã 䜿çšããã¡ã¢ãªãå€ãã»ã©ãã¬ããŒãžã³ã¬ã¯ã¿ãŒã®åäœã掻çºã«ãªããã¢ããªã±ãŒã·ã§ã³ã®é床ãäœäžããŸãã ãã®ãããããŒãã§ã¯ããªãŒã¯ã¯ããã©ãŒãã³ã¹ã«çŽæ¥åœ±é¿ããŸãã
- ãªãŒã¯ã¯ä»ã®åé¡ã«ã€ãªããå¯èœæ§ããããŸãã ã³ãŒããæŒãããšãéããããªãœãŒã¹ããããã¯ãããå¯èœæ§ããããŸãã ãã¡ã€ã«èšè¿°åãäžè¶³ããããããŒã¿ããŒã¹ãžã®å¥ã®æ¥ç¶ãéãããšãã§ããªãå ŽåããããŸãã ãã®ãããªåé¡ã¯ãã¡ã¢ãªãäžè¶³ãããã£ãšåã«çºçããå¯èœæ§ããããŸãããã¢ããªã±ãŒã·ã§ã³ãã¯ã©ãã·ã¥ããããšã¯ãããŸããã
- é
ããæ©ãããã¢ããªã±ãŒã·ã§ã³ã¯ã¯ã©ãã·ã¥ããŸãã ãããŠãããã¯èšªåè
ã®æµå
¥äžã«çºçããå¯èœæ§ããããŸãã 誰ããããªããç¬ããããã«ãŒãã¥ãŒã¹ã§ããªãã«ã€ããŠã®å«ãªããšãæžããŸãã
èœäžããé³ã¯ã©ãããæ¥ãã®ã§ããïŒ
è€éãªã¢ããªã±ãŒã·ã§ã³ã«ã¯ããªãŒã¯ãçºçããå¯èœæ§ã®ããå ŽæããããããããŸãã ããããæãæåã§çãå Žæ-ééã ã¯ããŒãžã£ã¯ãã¹ã³ãŒãããã®å€æ°åç
§ãé·æéä¿åã§ãããããæãé »ç¹ã«ãªãŒã¯ãããã€ã³ãã«ãªããŸãã
äžéšã®ãªãŒã¯ã¯ãã³ãŒãã§ããããæ¢ãã ãã§é
ããæ©ããæ€åºã§ããŸãããNodeã®éåæã®äžçã§ã¯ãã³ãŒã«ããã¯ã®åœ¢ã§å€ãã®ã¯ããŒãžã£ãŒãåžžã«äœæããŸãã ãããŠãäœæããããã£ãããšåäœããå Žåãåã³ãŒã«ããã¯ã®ã¡ã¢ãªãã©ã°ã¡ã³ããç©ã¿äžãããããããçŸåšã¯ãŸã£ããèŠããªãã³ãŒããçŸåšã®ãã®ãšåãããã«åäœããŸãã ãã®ãããªæŒãã远跡ããããšã¯ã¯ããã«å°é£ã§ãã
ã¢ããªã±ãŒã·ã§ã³ã¯ãäŸåããŠããä»ã®èª°ãã®ã³ãŒãã®ãšã©ãŒãåå ã§ãªãŒã¯ããããšããããŸãã ããã°ã©ã å
ã§ãªãŒã¯ã®åå ãšãªãå ŽæãèŠã€ããããšãã§ããå ŽåããããŸãããå®å
šã«ãããã°ãããã³ãŒããèŠãŠãå°æããŠãã©ã®ããã«ãªãŒã¯ããã®ãçåã«æã£ãŠããã ãã§ãã
node-memwatchã®å¿
èŠæ§ãçã¿åºããã®ã¯ã远跡ãå°é£ãªãããã®ãªãŒã¯ã§ãã äŒèª¬ã«ããã°ãæ°ãæåãç§ãã¡ã®ããã°ã©ããŒã®ãã€ãã»ãã©ãšã«ã¯2æ¥éã¯ããŒãŒããã«èº«ãåºããéåžžã«éãè² è·ã®ããšã§ã®ã¿çºçãããªãŒã¯ã远跡ããããšããŸããïŒãšããã§ã圌ã¯ãã®ã·ãªãŒãºã®æ¬¡ã®èšäºã®èè
ã§ãããåã«è² è·ãã¹ãã«å°å¿µããŠããŸãïŒ
2æ¥éã®æ€çŽ¢ã®åŸã圌ã¯ç®çã®ãšã©ãŒãNodeã«ãŒãã«ã«ããããšãçºèŠããŸããïŒ
http.ClientRequest
ã€ãã³ããã³ãã©ãŒã¯ã¡ã¢ãªãé©åã«è§£æŸããŸããã§ããïŒãã®ãšã©ãŒãä¿®æ£ããããã®ãããã¯Node.jsã³ãŒã
ã«2ã€ã ãã®
éåžžã«éèŠãªæåãè¿œå ããŸããïŒã æ·åã¯ããã€ãã«ãã®ãããªæŒæŽ©ãæãã®ã«åœ¹ç«ã€ããŒã«ãæžãããšãäœåãªããããŸããã
ãªãŒã¯æ€åºããŒã«
Node.jsã¢ããªã±ãŒã·ã§ã³ã§ãªãŒã¯ãæ€åºããããã®ããŒã«ã®éžæè¢ã¯ããã§ã«å¢ãç¶ããŠããŸãã ãããã®ããã€ãã次ã«ç€ºããŸãã
- node-mtrace JimbEsserãGCCmtraceãŠãŒãã£ãªãã£ã䜿çšããŠããŒã䜿çšéããããã¡ã€ã«ããŸãã
- Dave Pachecoã®node-heap-dumpãV8ããŒãã®ã¹ãããã·ã§ãããååŸããããã巚倧ãªJSONãã¡ã€ã«ã«æžã蟌ã¿ãŸãã JavaScriptã䜿çšããŠãã®ã¹ãããã·ã§ããã調æ»ããã³è§£æããããã®ããŒã«ãå«ãŸããŠããŸãã
- V8ãããã¡ã€ã©ãŒãšWebKit Webã€ã³ã¹ãã¯ã¿ãŒãããã¬ãŒã«åºã¥ããDanny Coatesã®v8ãããã¡ã€ã©ãŒãšããŒãã€ã³ã¹ãã¯ã¿ãŒã
- Felix Geisendorferã®Node ã¡ã¢ãªãªãŒã¯ã¬ã€ã ãv8ãããã¡ã€ã©ãŒãšããŒãã€ã³ã¹ãã¯ã¿ãŒã䜿çšããåºæ¬ã«ã€ããŠç°¡æœãã€æ確ã«èª¬æããŠããŸãã
- Joyent SmartOSãã©ãããã©ãŒã ãNode.jsã®ãªãŒã¯ããã©ãã«ã·ã¥ãŒãã£ã³ã°ããããã®è±å¯ãªããŒã«ãæäŸããŸãã
ç§ãã¡ã¯ãããã®ããŒã«ãä»ã®å€ãã®ããŒã«ã奜ãã§ãããã©ããç§ãã¡ã®ç°å¢ã«çæ³çãªãã®ã§ã¯ãããŸããã§ããã Web Inspectorã¯éçºäžã®ã¢ããªã±ãŒã·ã§ã³ã«ã¯æé©ã§ãããç¹ã«å€ãã®ãµãŒããŒãšããã»ã¹ã䜿çšãããŠããå ŽåãæŠéäžã®å®è¡äžã®ã¢ããªã±ãŒã·ã§ã³ã§ã®äœ¿çšã¯å°é£ã§ãã ãããã£ãŠããã®å©ããåããŠãããã«è¡šç€ºããããé«è² è·ã®ç¶æ
ã§ã®ã¿çºçãããšã©ãŒããã£ããããããšã¯å°é£ã§ãã dtraceãlibumemãªã©ã®ããŒã«ãåªããŠããŸããããã¹ãŠã®ãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã§åäœããããã§ã¯ãããŸããã
äŒãïŒnode-memwatch
è¿œå ããŒã«ãå¿
èŠãšããªãã¯ãã¹ãã©ãããã©ãŒã ãããã°ã©ã€ãã©ãªãå¿
èŠã§ããããã®ã©ã€ãã©ãªã䜿çšããŠãã¡ã¢ãªãªãŒã¯ã®å Žæãšåå ãèŠã€ããããšãã§ããŸããã ãããŠã
node-memwatchãæžã
ãŸãã ã
次ã®3ã€ã®ããšãæäŸããŸãã
- ãªãŒã¯ã€ãã³ã
memwatch.on('leak', function(info) {
- ã€ãã³ã
'stats'
var memwatch = require('memwatch'); memwatch.on('stats', function(stats) {
- ã¯ã©ã¹è¿œè·¡ããŒãã®å·®åïŒ
var hd = new memwatch.HeapDiff();
ããã«ãã¬ããŒãžã³ã¬ã¯ã¿ãŒã匷å¶çã«åŒã³åºãæ©èœããããŸããããã¯ãã¹ãã«åœ¹ç«ã€å ŽåããããŸãã ã€ãŸããçµå±ã®ãšããã3ã€ã§ã¯ãªã4ã€ã®ããšã§ãã
var stats = memwatch.gc();
memwatch.onïŒ 'stats'ã...ïŒïŒã¬ããŒãžã³ã¬ã¯ã·ã§ã³åŸã®ããŒãçµ±èš
node-memwatchã¯ãã¬ããŒãžã³ã¬ã¯ã¿ãŒã®åäœãçµäºããçŽåŸãã¡ã¢ãªãæ°ãããªããžã§ã¯ãã«å²ãåœãŠãããåã«ãããŒã䜿çšéã®çµ±èšã衚瀺ã§ããŸãã ãããè¡ãã«ã¯ã
V8::AddGCEpilogueCallback
䜿çšããŸãã
çµ±èšã«ã¯æ¬¡ã®ãã£ãŒã«ããå«ãŸããŸãã
- usage_trend
- current_base
- æšå®ããŒã¹
- num_full_gc
- num_inc_gc
- heap_compactions
- å
- æ倧
ããã¯ããªãŒã¯ããŠããã¢ããªã±ãŒã·ã§ã³ã®ã¡ã¢ãªäœ¿çšçµ±èšãã©ã®ããã«èŠãããã瀺ãäŸã§ãã ãžã°ã¶ã°ã®ç·è²ã®ç·ã¯ã
process.memoryUsage()
ã«ããã¡ã¢ãªäœ¿çšéã瀺ããèµ€è²ã®ç·ã¯ãããŒãmemwatchçµ±èšããã®
current_base
å€ã瀺ããŸãã å·Šäžã¯è¿œå ããŒã¿ã§ãã
å¢åã¬ããŒãžã³ã¬ã¯ã·ã§ã³ãçºçããé »åºŠã«æ³šæããŠãã ããã ããã¯ãV8ãèšæ¶ãæ¶å»ããªããæ±ããããªããã°ãªããªãããšã瀺ãèŠåãµã€ã³ã§ãã
memwatch.onïŒ 'leak'ã...ïŒïŒã¡ã¢ãªäœ¿çšéã®ãã€ããã¯ã¹
åçŽãªãã¥ãŒãªã¹ãã£ãã¯ã䜿çšããŠãæœåšçãªãªãŒã¯ãèŠåããŸãã 5åé£ç¶ããŠã¬ããŒãžã³ã¬ã¯ã·ã§ã³ãè¡ã£ãåŸãã¡ã¢ãªäœ¿çšéãå¢å ãããšãããªãŒã¯ãã€ãã³ããããªã¬ãŒãããŸãã ãªãŒã¯ã®å¯èœæ§ã«é¢ããæ
å ±ã¯ãèªã¿ããã䟿å©ãªåœ¢åŒã§è¡šç€ºãããŸãã
{ start: Fri, 29 Jun 2012 14:12:13 GMT, end: Fri, 29 Jun 2012 14:12:33 GMT, growth: 67984, reason: 'heap growth over 5 consecutive GCs (20s) - 11.67 mb/hr' }
memwatch.HeapDiffïŒïŒïŒãªãŒã¯ãèŠã€ãã
æåŸã«ãnode-memwatchã¯ãã¡ã¢ãªãå æãããªããžã§ã¯ãã®æ°ã®ååãå«ãããŒãã¹ãããã·ã§ãããæ¯èŒã§ããŸãã Diffã¯äŸµå
¥è
ãèŠã€ããã®ã«åœ¹ç«ã¡ãŸãã
var hd = new memwatch.HeapDiff();
diff
ãªããžã§ã¯ãã®å
容ã¯æ¬¡ã®ããã«ãªããŸãã
{ "before": { "nodes": 11625, "size_bytes": 1869904, "size": "1.78 mb" }, "after": { "nodes": 21435, "size_bytes": 2119136, "size": "2.02 mb" }, "change": { "size_bytes": 249232, "size": "243.39 kb", "freed_nodes": 197, "allocated_nodes": 10007, "details": [ { "what": "Array", "size_bytes": 66688, "size": "65.13 kb", "+": 4, "-": 78 }, { "what": "Code", "size_bytes": -55296, "size": "-54 kb", "+": 1, "-": 57 }, { "what": "LeakingClass", "size_bytes": 239952, "size": "234.33 kb", "+": 9998, "-": 0 }, { "what": "String", "size_bytes": -2120, "size": "-2.07 kb", "+": 3, "-": 62 } ] } }
HeapDiff
ã¯ãçµ±èšæ
å ±ãåéããåã«ã¬ããŒãžã³ã¬ã¯ã¿ãŒãåŒã³åºããŠãããŒã¿ã«äžèŠãªãã³ã»ã³ã¹ãå€ãå«ãŸããªãããã«ããŸãã
'stats'
ã€ãã³ãã¯çºçããªãããã
'stats'
ãã³ãã©ãŒå
ã§
HeapDiff
ãå®å
šã«åŒã³åºãããšãã§ããŸãã
以äžã¯ãããŒãäžã®æãã¹ããŒã¹ãå æãããªããžã§ã¯ãã®ãªã¹ããè¿œå ããçµ±èšã®äŸã§ãã
次ã¯ïŒ
node-memwatchã®æ©èœïŒ
- ã¡ã¢ãªäœ¿çšéã®æ£ç¢ºãªè¿œè·¡ã
- æŒãã®å¯èœæ§ã®éç¥ã
- å·®åããŒããååŸããããã®ããŒã«ã
- ã¯ãã¹ãã©ãããã©ãŒã ;
- ä»ã®ããŒã«ãžã®äŸåé¢ä¿ã®æ¬ åŠã
ãã£ãšæ¬²ããã ç¹ã«ãnode-memwatchãæµãããªããžã§ã¯ãã®ç¹å®ã®ããŒã¿ïŒå€æ°ã®ååãé
åã€ã³ããã¯ã¹ãã¯ããŒãžã£ãŒã³ãŒãã®æçïŒãæäŸã§ããããã«ããããšèããŠããŸãã
ãªãŒã¯ããŠããNode.jsã¢ããªã±ãŒã·ã§ã³ããããã°ãããšãã«node-memwatchã圹ã«ç«ã€ããšãé¡ã£ãŠããŸããããããã©ãŒã¯ããŠãæ¹åã«åå ããŠãã ããã
ãµã€ã¯ã«ã®ãã¹ãŠã®èšäºïŒ