首頁 >web前端 >js教程 >記憶體洩漏是什麼以及如何解決

記憶體洩漏是什麼以及如何解決

清浅
清浅原創
2019-03-16 11:49:434033瀏覽

記憶體洩漏指的是當一個物件不起作用時應該被回收時卻因為另一個物件對它的引用而導致它不能被回收,留在了堆記憶體中就稱為記憶體洩漏。常見的有意外全域變量,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程式中加入,開啟嚴格模式'use strict',可以有效地避免上述問題。

注意:用來暫時儲存大量資料的全域變量,在確保處理完這些資料後要將其設為null或重新賦值。

2、DOM洩漏

在瀏覽器中DOM和JS所採用的引擎是不一樣的,DOM採用的是渲染引擎,而JS採用的是v8引擎,所以在用JS操作DOM時會比較耗費效能,所以為了減少DOM的操作,我們會採用變數引用的方式會將其快取在目前環境。如果在進行一些刪除、更新操作之後,可能會忘記釋放已經快取的DOM因此造成了記憶體洩漏

例:對

沒有清理的DOM元素引用

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

解決方法:設定refA = null;

3、被遺忘的計時器和回呼函數

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

這樣的程式碼很常見, 如果id為Node的元素從DOM中移除, 該定時器仍會存在, 同時, 因為回呼函數中包含對someResource的引用, 定時器外面的someResource也不會被釋放

4、循環引用

在js的記憶體管理環境中,如果物件A 對B有存取物件的權限,就稱為物件A 引用物件B。引用的計數的策略就是看對像有沒有其他對象引用到它,如果沒有對象引用這個對象,那麼這個對象將會被回收 。

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  }

當函數執行結束後,返回值為undefined,所以整個函數以及內部的變數都應該被回收,但根據引用計數方法,obj1 和obj2 的引用次數都不為0,所以他們不會被回收。所以要解決這個問題可以設定它們的值為null

總結:以上就是本篇文章的全部內容了,希望對大家有幫助。

以上是記憶體洩漏是什麼以及如何解決的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn