ホームページ  >  記事  >  ウェブフロントエンド  >  メモリリークとは何か、そしてその修正方法

メモリリークとは何か、そしてその修正方法

清浅
清浅オリジナル
2019-03-16 11:49:434001ブラウズ

メモリ リークとは、オブジェクトが無効でリサイクルされるべきであるにもかかわらず、別のオブジェクトがそのオブジェクトを参照しているためにリサイクルできず、ヒープ メモリに残ったままになることをメモリ リークと呼びます。一般的なものには、予期しないグローバル変数、DOM リーク、循環参照などが含まれます。

メモリリークとは何か、そしてその修正方法

[推奨コース: JavaScript チュートリアル]

メモリ リーク

メモリ リークとは、通常、オブジェクトに影響がなく、リサイクルする必要がある場合を指します。使用中の別のオブジェクトは参照のためリサイクルできません。リサイクルできないこのオブジェクトはヒープ メモリに残り、メモリ リークが発生します。

オブジェクトが不要になったときリサイクルされるオブジェクトが使用されている場合、使用中の別のオブジェクトがそのオブジェクトへの参照を保持しているため、リサイクルされません。これにより、リサイクルされるべきオブジェクトがリサイクルされずにヒープ メモリに残り、メモリ リークが発生します。

一般的なメモリ リーク:

1. 予期しないグローバル変数

Js が未定義の変数を処理する方法: 未定義 変数は新しい変数を作成しますグローバル オブジェクト内の変数。ブラウザでは、グローバル オブジェクトは window です。

function foo(arg) { 
bar = "this is a hidden global variable"; //等同于window.bar="this is a hidden global variable"
this.bar2= "potential accidental global";//这里的this 指向了全局对象(window),
等同于window.bar2="potential accidental global"}

解決策: 上記の問題を効果的に回避するには、JavaScript プログラムに strict モード「use strict」を追加して有効にします。

注: 大量のデータを一時的に保存するために使用されるグローバル変数は、データが処理されたことを確認した後に null に設定するか、再割り当てする必要があります。

2. DOM リーク

ブラウザでは、DOM と JS で使用されるエンジンが異なります。DOM はレンダリング エンジンを使用し、JS は v8 エンジンを使用するため、 DOMを操作するJSはパフォーマンスを消費するので、DOM操作を軽減するために変数参照を使用して現在の環境にキャッシュします。削除および更新操作を実行すると、キャッシュされた DOM の解放を忘れてメモリ リークが発生する可能性があります。

例: 未クリーンの DOM 要素への参照

var refA = document.getElementById('refA');
document.body.removeChild(refA); // #refA不能回收,因为存在变量refA对它的引用。
将其对#refA引用释放,但还是无法回收#refA。

解決策: Set refA = null;

3. 忘れられたタイマーとコールバック関数

var someResource = getData();
setInterval(function() {
    var node = document.getElementById('Node');
    if(node) {
        node.innerHTML = JSON.stringify(someResource));
    }
}, 1000);

ID を持つ要素が Node If の場合、DOM から削除された場合、このようなコードは非常に一般的です。 、タイマーはまだ存在します。同時に、コールバック関数には someResource への参照が含まれているため、タイマーの外にある someResource は解放されません。

4. 循環参照

js のメモリ管理環境では、オブジェクト A がオブジェクト B へのアクセス権限を持っている場合、オブジェクト B を参照するオブジェクト A と呼ばれます。参照カウント方式では、そのオブジェクトを参照する他のオブジェクトがあるかどうかを確認し、そのオブジェクトを参照するオブジェクトがない場合、そのオブジェクトはリサイクルされます。

var obj1 = { a: 1 }; // 一个对象(称之为 A)被创建,赋值给 obj1,A 的引用个数为 1  
var obj2 = obj1; // A 的引用个数变为 2  
 obj1 = 0; // A 的引用个数变为 1 
 obj2 = 0; // A 的引用个数变为 0,此时对象 A 就可以被垃圾回收了

しかし、参照カウントに関する最大の問題は循環参照です。

function func() {  
    var obj1 = {};  
    var obj2 = {};  
    obj1.a = obj2; // obj1 引用 obj2  
    obj2.a = obj1; // obj2 引用 obj1  }

関数実行時の戻り値は不定なので関数全体と内部変数を再利用する必要がありますが、参照カウント方式によりobj1とobj2の参照数が0になりません。 、したがって、それらはリサイクルされません。したがって、この問題を解決するには、値を null に設定します。

要約: 上記がこの記事の全内容です。皆様のお役に立てれば幸いです。

以上がメモリリークとは何か、そしてその修正方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。