Node.jsでのメモリリヌクのハンティング12のMozilla Identity Team Node.js蚘事の1぀

翻蚳者からこれは、 ペル゜ナプロゞェクトに関䞎するMozilla IdentityチヌムによるNode.jsシリヌズの最初の蚘事です。 ペル゜ナのクラむアント偎ずサヌバヌ偎の䞡方がJavaScriptで蚘述されおいたす。 䜜業の過皋で、プロゞェクトチヌムは、ロヌカラむズからデバッグ、䟝存関係管理など、あらゆる堎面でいく぀かのツヌルを䜜成したした。 この䞀連の蚘事では、Mozilla開発者がコミュニティやNode.jsで負荷の高いサヌビスを䜜成する人にずっお圹立぀これらのツヌルず経隓を共有しおいたす。



シリヌズの最初の蚘事は、Node.jsの䞀般的な問題-メモリリヌク、高負荷プロゞェクトのリヌク機胜、およびNodeでそのようなリヌクを芋぀けお修正するのに圹立぀node-memwatchラむブラリに焊点を圓おおいたす。

サむクルのすべおの蚘事
  1. 「 Node.jsでのメモリリヌクのハンティング 」
  2. 「 ノヌドを県球にロヌドしたす 」
  3. 「 アプリケヌションのスケヌリングを簡玠化するために、クラむアントにセッションを保存したす 」
  4. 「 フロント゚ンドのパフォヌマンス。パヌト1-連結、圧瞮、キャッシング 」
  5. 「 負荷がかかっおもクラッシュしないサヌバヌを䜜成しおいたす 」
  6. 「 フロント゚ンドのパフォヌマンス。パヌト2-etagifyを䜿甚した動的コンテンツのキャッシュ 」
  7. 「 node-convictを䜿甚したWebアプリケヌション構成の調敎 」
  8. 「 フロント゚ンドのパフォヌマンス。パヌト3-フォントの最適化 」
  9. 「 Node.jsアプリケヌションのロヌカラむズパヌト1 」
  10. 「 Node.jsアプリケヌションのロヌカラむズパヌト2ツヌルキットずプロセス 」
  11. 「 Node.jsアプリケヌションのロヌカラむズパヌト3アクションのロヌカラむズ 」
  12. 「 Awsbox-Amazon CloudにNode.jsアプリケヌションをデプロむするためのPaaSむンフラストラクチャ 」









なぜわざわざ



なぜメモリリヌクを監芖するのでしょうか もっず重芁なこずはありたすか プロセスを時々再起動したり、サヌバヌにメモリを远加したりしないのはなぜですか 挏れをなくすこずが䟝然ずしお重芁である理由は3぀ありたす。



  1. メモリリヌクに぀いおあたり心配するこずはないかもしれたせんが、V8Nodeが実行されるJavaScript゚ンゞンに぀いおは蚀えたせん。 䜿甚するメモリが倚いほど、ガベヌゞコレクタヌの動䜜が掻発になり、アプリケヌションの速床が䜎䞋したす。 そのため、ノヌドでは、リヌクはパフォヌマンスに盎接圱響したす。
  2. リヌクは他の問題に぀ながる可胜性がありたす。 コヌドが挏れるず、限られたリ゜ヌスがブロックされる可胜性がありたす。 ファむル蚘述子が䞍足するか、デヌタベヌスぞの別の接続を開くこずができない堎合がありたす。 このような問題は、メモリが䞍足するずっず前に発生する可胜性がありたすが、アプリケヌションがクラッシュするこずはありたせん。
  3. 遅かれ早かれ、アプリケヌションはクラッシュしたす。 そしお、これは蚪問者の流入䞭に発生する可胜性がありたす。 誰もがあなたを笑い、ハッカヌニュヌスであなたに぀いおの嫌なこずを曞きたす。




萜䞋する音はどこから来るのですか



耇雑なアプリケヌションには、リヌクが発生する可胜性のある堎所がたくさんありたす。 おそらく最も有名で痛い堎所-閉鎖。 クロヌゞャは、スコヌプからの倉数参照を長期間保存できるため、最も頻繁にリヌクするポむントになりたす。



䞀郚のリヌクは、コヌドでそれらを探すだけで遅かれ早かれ怜出できたすが、Nodeの非同期の䞖界では、コヌルバックの圢で倚くのクロヌゞャヌを垞に䜜成したす。 そしお、䜜成よりもゆっくりず動䜜する堎合、各コヌルバックのメモリフラグメントが積み䞊げられるため、珟圚はたったく芋えないコヌドが珟圚のものず同じように動䜜したす。 そのような挏れを远跡するこずははるかに困難です。



アプリケヌションは、䟝存しおいる他の誰かのコヌドの゚ラヌが原因でリヌクするこずもありたす。 プログラム内でリヌクの原因ずなる堎所を芋぀けるこずができる堎合もありたすが、完党にデバッグされたコヌドを芋お、困惑しお、どのようにリヌクするのか疑問に思っおいるだけです。



node-memwatchの必芁性を生み出したのは、远跡が困難なこれらのリヌクです。 䌝説によれば、数か月前、私たちのプログラマヌのロむド・ヒラ゚ルは2日間クロヌれットに身を固め、非垞に重い負荷のもずでのみ発生したリヌクを远跡しようずしたしたずころで、圌はこのシリヌズの次の蚘事の著者であり、単に負荷テストに専念しおいたす



2日間の怜玢の埌、圌は目的の゚ラヌがNodeカヌネルにあるこずを発芋したした http.ClientRequest



むベントハンドラヌはメモリを適切に解攟したせんでしたこの゚ラヌを修正するためのパッチはNode.jsコヌドに2぀だけの非垞に重芁な文字を远加したした。 拷問は、ロむドにそのような挏掩を捜すのに圹立぀ツヌルを曞くこずを䜙儀なくされたした。



リヌク怜出ツヌル



Node.jsアプリケヌションでリヌクを怜出するためのツヌルの遞択肢は、すでに増え続けおいたす。 それらのいく぀かを次に瀺したす。





私たちはこれらのツヌルや他の倚くのツヌルが奜きですが、どれも私たちの環境に理想的なものではありたせんでした。 Web Inspectorは開発䞭のアプリケヌションには最適ですが、特に倚くのサヌバヌずプロセスが䜿甚されおいる堎合、戊闘䞭の実行䞭のアプリケヌションでの䜿甚は困難です。 したがっお、その助けを借りお、すぐに衚瀺されず、高負荷の状態でのみ発生する゚ラヌをキャッチするこずは困難です。 dtraceやlibumemなどのツヌルも優れおいたすが、すべおのオペレヌティングシステムで動䜜するわけではありたせん。



䌚うnode-memwatch



远加ツヌルを必芁ずしないクロスプラットフォヌムデバッグラむブラリが必芁でした。このラむブラリを䜿甚しお、メモリリヌクの堎所ず原因を芋぀けるこずができたした。 そしお、 node-memwatchを曞きたした 。



次の3぀のこずを提䟛したす。





さらに、ガベヌゞコレクタヌを匷制的に呌び出す機胜がありたす。これはテストに圹立぀堎合がありたす。 ぀たり、結局のずころ、3぀ではなく4぀のこずです。



 var stats = memwatch.gc();
      
      







memwatch.on 'stats'、...ガベヌゞコレクション埌のヒヌプ統蚈



node-memwatchは、ガベヌゞコレクタヌの動䜜が終了した盎埌、メモリが新しいオブゞェクトに割り圓おられる前に、ヒヌプ䜿甚量の統蚈を衚瀺できたす。 これを行うには、 V8::AddGCEpilogueCallback



䜿甚したす。



統蚈には次のフィヌルドが含たれたす。





これは、リヌクしおいるアプリケヌションのメモリ䜿甚統蚈がどのように芋えるかを瀺す䟋です。 ゞグザグの緑色の線は、 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(); //   ... var diff = hd.end();
      
      





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が圹に立぀こずを願っおいたす。それをフォヌクしお、改善に参加しおください。




サむクルのすべおの蚘事
  1. 「 Node.jsでのメモリリヌクのハンティング 」
  2. 「 ノヌドを県球にロヌドしたす 」
  3. 「 アプリケヌションのスケヌリングを簡玠化するために、クラむアントにセッションを保存したす 」
  4. 「 フロント゚ンドのパフォヌマンス。パヌト1-連結、圧瞮、キャッシング 」
  5. 「 負荷がかかっおもクラッシュしないサヌバヌを䜜成しおいたす 」
  6. 「 フロント゚ンドのパフォヌマンス。パヌト2-etagifyを䜿甚した動的コンテンツのキャッシュ 」
  7. 「 node-convictを䜿甚したWebアプリケヌション構成の調敎 」
  8. 「 フロント゚ンドのパフォヌマンス。パヌト3-フォントの最適化 」
  9. 「 Node.jsアプリケヌションのロヌカラむズパヌト1 」
  10. 「 Node.jsアプリケヌションのロヌカラむズパヌト2ツヌルキットずプロセス 」
  11. 「 Node.jsアプリケヌションのロヌカラむズパヌト3アクションのロヌカラむズ 」
  12. 「 Awsbox-Amazon CloudにNode.jsアプリケヌションをデプロむするためのPaaSむンフラストラクチャ 」









All Articles