JavaScriptのメモリリークに幼児ガイド


この記事では、メモリリークを理解する上で非常に単純なアプローチを取ります.また、それらを診断しようとします.
豊富なメモリの今日の世界では、我々はめったにメモリリークについて心配する.しかし、私は我々が現実の世界に住んでいるとあなたに話すのが嫌いです、そして、何も無料で来ません.

私のファンシー機能プログラミング
ディスクロージャー:私は絶対に機能プログラミングが大好きです.
機能的プログラミングはクールであり、新しいES 6の構文では、さらにクールになります.
const arrayAddFirst = (a, b) => [a, ...b];
上の例はとてもいいですね.私と一緒にbroプログラムをしない限り、私は盲目的に重いデューティループの中に入れて😎.
result = newData.reduce((p,r) => arrayAddFirst(r, p), []); 
現在、私はあなたに上記のばかなコードのために私を判断して欲しくありません.(仮想のハグなら、それが何をするかを推測できます😁)

for(var i = 0; i < newData.length; i++) {
    for(var j = 0; j < i; i++) {
        // stuff here
    }
}
上記のコードスニペットは、私たちの例の古いやり方です.それが実行されるのを見るのがどれくらい簡単かに注意してくださいn * (n+1) / 2 タイムズnnewData .
この例のコードの主な問題は、ガベージコレクターが頻繁にキックしなければならないことです.空想[a, ...b] 配列を作成する.reduce ループはメモリから削除する必要があります.
この例は、記憶があなたの親友でないという重要な事実に光を当てることを試みる.それはあなたの好みの時間の99 %で動作しますが、それが刺すことを決定するとき、それは直接目に刺す.


メモリリーク.
一般にJavaScriptアプリケーションは2つの方法で凍結できます.
無限ループ:あなたが偶然に終わることのないループを書いたかもしれません.
var x = 0;
while(x < 5) {
   console.log(x); // Warning! do not try this at home 
}
メモリ不足している:私たちはすべてのコンピュータにメモリの量が限られている知っているし、我々は注意していない場合は、すべてのメモリのホギングを終了する可能性があります.
var x = [ [1] ];
for(var i = 1; i < 100000; i++) {
    x.push(arrayAddFirst(i, x[i-1])); // Warning! do not try this at home 
}

しかし、メモリリークはどうですか?
もちろん、慎重にこれらの悪い行動を避けることができます.しかし、メモリリークは静かに座っている厄介な悪魔の一つです.
無限の資源を持つコンピュータを定義し、それを呼びましょうDeep thought . を参照してくださいDeep thought この記事でDT-42 そして、あなたはすぐに我々が使用する方法を参照してくださいDT-42 メモリリークを把握する.

メモリリーク
簡単な用語でのメモリリークは永遠に使用されるのを待ってデータを忘れています.
科学的定義にジャンプする前に例を見てみよう.

function sayHi() {
    var allNames = [];
    var emoji = '👋';
    return name => {
        allNames.push(name);
        return emoji + name;
        }
} 
例では、我々のプログラムは、我々がそれを呼ぶたびに太っています.ガベージコレクターはクリーンアップできませんallNames データをプッシュする必要があるためです.それは、allnamesが決して読まれることができないことを理解することができません、したがって、それは記憶においてどんなスペースでも与えることが無駄です.
ウィキペディアは言います.

memory leak is a type of resource leak that occurs when a computer program incorrectly manages memory allocations[1] in such a way that memory which is no longer needed is not released.


私は、それが症状として考えて、概念を理解するのがより簡単であるとわかります.あなたのプログラムは、記憶のための愛が縛られずに増加し続ける患者です.

ほとんどの時間は、コンピュータ(ガベージコレクター)は、あなたがもう使用していないデータのほとんどを発見するのに十分ですし、あなたのためにそれをクリーンアップします.しかし、それは完璧でありません、そして、我々は人間より賢いガベージコレクターを持つことから遠いです.(もし私たちが1つを持っていれば、コードを書くことはできません.

本当の生命漏れをください
私たちの本当の生活の問題は、私たちがそのような些細なメモリリークに遭遇しないということです、そして、リークが一見よく振る舞うようなコードの後ろに潜んでいるということですarrayAddFirst ). 代わりに実際の生活のリークをスローする代わりにどのようにメモリリークを識別する方法を示します.
メモリリークを診断するためにクロムを発射しましょう.
  • 空のページを開きます.
  • DEVパネル(コマンド+オプション+ iまたは制御+ shift + i )を開きます.
  • このサンプルコードをコンソールにペーストします.
  • function sayHi() {
        var allNames = [];
        return name => {
                allNames.push(name);
                return '👋 ' + name;
            }
    }
    var hello = sayHi();
    hello('Gandhi');
    
    さて、私たちはすでにメモリを漏らし始めましたmemory profiler .
    あなたはそれをAとして見つけることができるはずですmemory devツールのタブ.

    この記事の範囲についてはTake Heap Snapshot . この機能は、プログラムの現在のメモリ使用量のスナップショットを取ります.
    私の場合はこんな感じです.

    偉大な、今我々は何度も我々の無実探し機能を実行します.
    for(var i=0; i<1000000; i++) {
        hello('Gandhi');
    }
    
    別のスナップショットを取る場合は、メモリ使用量が増加します.

    私の場合では、10メガバイトの完全な違いがあります.実際の生活の多くのケースでは、いくつかのメガバイトのジャンプが正常である可能性がありますし、時間のスパンで複数のスナップショットを取る必要がありますリークを除外する.
    をクリックして簡単に2つのスナップショットを比較することができますSummary ドロップダウンと切り替えComparison .

    あなたがあなたの新しいスナップショットをあなたが以前取ったものと比較して、置くならば#Delta 降りるには、巨大な数を見つける(string) . これは私たちの記憶が漏れているところです.それをクリックすると、多くのGandhi 's.
    私は本当にこの記事はメモリを理解するのに役立つ願っています.これは漏れを診断するためにいくつかのアプローチの1つです.以下のリンクをチェックしてください.
  • Memory management
  • Memory Bloat in Node.js
  • あなたならば❤️ この記事を共有するには、この記事を共有してください.
    Twitterで私に手を差し伸べる.