Node.js学習ノート(五)

5136 ワード

メモリ制御
ブロックなし、イベント駆動によって確立されたNodeサービスは、メモリ消費が低いという利点があり、大容量のネットワーク要求を処理するのに非常に適している.
1.V 8のゴミ回収メカニズムとメモリ制限
性能に敏感なサーバプログラムに対して、メモリ管理の良し悪し、ゴミ回収の状況が優れているかどうかは、サービスに影響を与えます.Nodeでは、これらはすべてNodeのJavaScript実行エンジンV 8に関連しています.
1.1 NodeとV 8
NodeはChromeのJavaScript実行時に構築されたプラットフォームです.
V 8の性能の利点は、JavaScriptで高性能バックグラウンドサービスプログラムを書くことを可能にする.
NodeはJavaScriptの実行においてV 8から直接に利益を得て、V 8のアップグレードによってより良い性能または新しい言語特性を享受できます.同時にV 8の制限を受けます.例えばメモリの制限などです.
1.2 V 8のメモリ制限
NodeではJavaScriptを通じてメモリを使用すると一部のメモリしか使えないことが分かります.(64ビットの約1.4 GB、32ビットの約0.7 G).
V 8のメモリ制限は、Nodeが直接メモリオブジェクトを操作できなくなります.
この問題を引き起こした主な原因はNodeがV 8に基づいて構築されているため、Nodeで使用されているJavaScriptオブジェクトは基本的にV 8自身の方式で分配と管理されている.
1.3 V 8の対象割当
V 8においては、すべてのJavaScriptオブジェクトは、スタックによって割り当てられます.
NodeはV 8のメモリ使用量の表示方法を提供しています.
$node;process.memoryUsage(){rss:22044672、heappTotal:9682944、heappUsed:5296232、/申請済みメモリexternal:8860] //使用済みメモリ
コードに変数を宣言し、値を指定すると、使用するオブジェクトのメモリがスタックに割り当てられます.すでに申請した空き容量が新しい対象に割り当てられていない場合、メモリの積み込みを継続して申請し、V 8の制限を超える大きさを知るまで.
V 8はなぜ山の大きさを制限しますか?
  • 表層の原因はV 8です.最初はブラウザのために設計されています.メモリをたくさん使う場面に遭遇することはあまりありません.
  • 深層原因はV 8のゴミ回収メカニズムの制限である.
  • 制限を開けてメモリをもっと使う:
    node--max-old-space-size=1700 test.js/単位はMB/またはnode--max-new-space-size=1024 test.js/単位はKBです.
    1.4 V 8のゴミ回収メカニズム
    V 8に使用される各種ゴミ回収アルゴリズム:
  • V 8の主なゴミ回収アルゴリズムV 8のゴミ回収戦略は主に分世代式ゴミ回収メカニズムに基づいています.近代的なごみの回収のアルゴリズムの中で対象の生存時間によってメモリのごみを回収して異なっている世代を行って、更にそれぞれ異なっている世代のメモリに対して更に高い効率の計算方法を行います.
  • V 8のメモリはV 8の中で分けて、主にメモリを新生代と老生世代の2世代に分けます.新生代の対象の生存時間が短い.老生世代の中の対象は長く生きていますか?それとも常駐メモリの対象ですか?V 8の山の全体の大きさは新生世代のメモリと老生世代のメモリの空間です.
  • Scabiengeアルゴリズムは世代別に基づいて、新生代の対象は主にScaavengeアルゴリズムによってゴミ回収を行う.Sceavengeの具体的な実現において、主にCheneyアルゴリズムを採用する.Cheneyアルゴリズムは複製方式で実現されるゴミ回収アルゴリズムである.ゴミを回収する過程で、生存対象を二つのセミソスペースで複製することです.Sceavengeの欠点:ヒープメモリの半分しか使えません.Scabiengeは典型的な犠牲空間と時間を交換するアルゴリズムですので、大規模にすべてのゴミ回収に適用できません.複数のオブジェクトが複製されても生存している場合、ライフサイクルが長いオブジェクトとして認識されます.このような長いライフサイクルのオブジェクトは、次の世代に移動され、新しいアルゴリズムで管理されます.対象が新しい世代から古い世代に移る過程を昇進といいます.
  • Mark-Sweep&Mark-CommpactMark-Sweepはマーククリアという意味で、マークとクリアの二つの段階に分けられます.Mark-Sweepの最大の問題は一回のマーキングクリアを行った後、メモリ空間が不連続な状態になります.Mark-Comppactはマークを整理するという意味で、Mark-Sweepに基づいて変化してきました.
  • Increment al Marking JavaScriptアプリケーションロジックとゴミ回収器が一致しないことを避けるために、ゴミ回収の3つの基本的なアルゴリズムは、アプリケーションロジックを停止し、実行後のゴミ回収を実行してから、アプリケーションロジックを実行する必要があります.このような行為は「完全停止」と呼ばれます.全ヒープのゴミ回収による停止時間を減らすために、V 8はまずマーク段階から始まり、一気に停止して完成するはずの動きをインクリメンタルマーキングに変更します.
  • 1.5ゴミ回収ログを確認する
    ゴミ回収ログを見る方法は、主に起動時に「トレイ」を追加します.gcパラメータゴミの回収を行う時は、標準出力からゴミ回収のログ情報を印刷します.
    ごみの回収ログを分析することによって、ゴミ回収の運行状況を知ることができます.ゴミ回収のどの段階が比較的に時間がかかりますか?トリガの原因は何ですか?
    2.メモリの効率的な使用
    V 8の前に、開発者の責任はどのようにしてゴミ回収メカニズムをより効率的に作動させるかです.
    2.1スコープ
    JavaScriptでは、スコープを形成することができる関数コール、with、およびグローバルスコープがあります.
  • 識別子検索
  • 作用分域チェーン
  • 変数のアクティブリリース常駐メモリを解放する必要があるオブジェクトは、delete操作によって参照関係を削除することができます.または変数の値を再割り当てし、古いオブジェクトを参照関係から逸脱させます.delete操作と再割当は同じ効果を持つが、V 8においてdelete削除対象の属性はV 8の最適化に干渉する可能性があり、すべては賦値によって参照を解除したほうが良い.
  • 2.2クローズド
    JavaScriptでは、外部作用領域を内部作用領域にアクセスする変数を実現する方法をクローズドといいます.これは高次関数の特性によるものである.関数はパラメータとしてもよいし、戻り値としてもよい.
    クローズドはJavaScriptの高級特性であり、それを利用して多くの巧妙な効果を生み出すことができます.変数がこの中間関数を参照すると、この中間関数は解放されず、元の作用領域も解放されず、作用領域で発生したメモリ占有率も解放されない.引用しない限り、徐々に解放されます.
    3.メモリ指標
    3.1メモリの使用状況を確認する
  • は、プロセスのメモリ占有率を調べてprocess.memoryUsageを呼び出すと、Nodeプロセスのメモリ占有状況が見られます.rssは、redent set sizeの略語であり、プロセスの常駐メモリ部分である.プロセスのメモリは全部でいくつかの部分があります.一部はrssで、残りはスワップまたはファイルシステムにあります.
  • は、システムのメモリ占有OSモジュールにおけるtotalmem()とfreem()を参照して、オペレーティングシステムのメモリ使用状況を確認する.システムの総メモリとアイドルメモリをそれぞれ返します.単位はバイトです.node>os.totalmem()8446971904>os.freem()2469531648>
  • 3.2ヒープ外メモリ
    ヒープ内のメモリ使用量は常にプロセスの常駐メモリ量より小さい.これはNode内のメモリ使用量がすべてV 8で割り当てられているわけではないことを意味する.V 8ではないメモリをヒープ外メモリと呼びます.
    ヒープ外メモリはメモリ制限を突破することができます.
    4.メモリリーク
    Nodeはメモリリークに対して非常に敏感で、一旦オンラインで何千何万もの流量が適用されると、バイトのメモリリークが一バイトでも蓄積され、ゴミ回収プロセスはより多くの時間をかけて対象のスキャンを行い、アプリケーションの応答が遅くなります.
    メモリ漏れの原因:
  • キャッシュ
  • 列の消費が適時ではない.
  • 作用領域が解放されていない.
  • 4.1メモリを慎重にキャッシュとする
    キャッシュは応用の役割において重要な役割を果たし、十分に効果的に資源を節約することができる.キャッシュのアクセス効率はI/Oよりも高く、キャッシュに命中するとI/Oの時間を一度に節約できます.
    対象がキャッシュとして使われると、それは老生時代に常駐することを意味します.キャッシュに保存されているキーが多ければ多いほど、長期的に生存しているオブジェクトも多くなります.これはゴミの回収をスキャンや整理を行っている間に、これらの対象を無駄にしてしまいます.
    JavaScript開発者は通常、オブジェクトのキーの値を使ってキャッシュすることが好きですが、これは厳密な意味でのキャッシュとは異なり、厳密な意味でのキャッシュは完全な期限切れ戦略を持っています.普通のオブジェクトのキーの値は正しいです.
    無意識によるメモリ漏れのシーン:memoize
    memoizeの原理は、パラメータをキーとしてキャッシュし、メモリ空間でCPU実行時間を切り替えることです.
  • キャッシュ制限ポリシーは、キャッシュ中のオブジェクトが永遠に解放されない問題を解決するために、キャッシュの無限成長を制限するためのポリシーを追加する必要がある.
  • キャッシュされたソリューションは、どのように大量のキャッシュを使用しますか?現在の比較的良い解決策は、プロセス外のキャッシュを採用しており、プロセス自体は格納されていません.外部のキャッシュソフトはキャッシュの有効期限が切れて淘汰戦略と自分のメモリ管理を持っています.Nodeプロセスの性能に影響しません.Nodeでは主に二つの問題を解決します.
  • はキャッシュを外部に転送し、常駐メモリの対象数を減らし、ゴミの回収をより効率的にする.
  • プロセス間でキャッシュを共有できます.
  •   ,         Redis Memcached。
    
    
    4.2キューの状態に注目する
    ほとんどの応用シーンでは、生産速度より消費速度がはるかに大きく、メモリリークが発生しにくい.しかし、生産速度より消費速度が低いと、積み立てられます.
    表層のソリューションは消費速度の高い技術に切り替えることです.
    深さの解決策は監視キューの長さである.
    5.メモリ漏れ検査
    1.node-heappunp
    2.node-memwatch
    6.大メモリアプリケーション
    Nodeは大ファイルを処理するためにstreamモジュールを提供します.