搜尋

首頁  >  問答  >  主體

foreach - JavaScript連寫時為什麼會有記憶體洩漏問題?

問題描述

在一個搜尋中發現了一個記憶體洩漏的問題,如圖所示:

#搜尋15次,記憶體由15MB上升到18MB,還是比較嚴重的。

問題排查

#經過調試分析,最後定位到問題的大致位置:

function searchData() {
    console.log('search');
    var sc = {};
    // 获取类名为fui-form下的所有mini控件,遍历将搜索条件形成下面的格式
    // {
    //     "控件id":"控件值"
    // }
    mini.getChildControls(document.getElementsByClassName('fui-form')[0]).forEach(function (item) {
        sc[item.id] = item.getValue();
    });
    console.log('搜索条件' + JSON.stringify(sc, 0, 4));
    grid.load();
}

將其除grid.load() 之外的全部註解掉,搜尋0次、1次、10次結果如下:

#可以看出記憶體搜尋次數的增加,記憶體是不成長的,不存在記憶體洩漏問題。

接著以為是console的問題,註解掉兩個console,結果如下(仍是搜尋0次、1次、10次):

#問題依舊,可以看出不是console的問題,其實想想也不可能,但是排查時候基本上就是病急亂投醫了。

下面基本上可以定位問題是這一段導致的了。

var sc = {};
mini.getChildControls(document.getElementsByClassName('fui-form')[0]).forEach(function (item) {
    sc[item.id] = item.getValue();
});

為了分析,可以將上面拆成兩個部分:取得控制項數組和遍歷組織資料

var sc = {};
var controls = mini.getChildControls(document.getElementsByClassName('fui-form')[0]);
controls.forEach(function (item) {
    sc[item.id] = item.getValue();
});

進行獲取與遍歷的拆分之後,再進行測試,問題居然不存在了,如圖:

#最終問題

#函數中取得控制項並遍歷的兩種寫法

寫法一:

// 获取并遍历
mini.getChildControls(document.getElementsByClassName('fui-form')[0]).forEach(function (item) {
    sc[item.id] = item.getValue();
});

寫法二:

// 获取控件
var controls = mini.getChildControls(document.getElementsByClassName('fui-form')[0]);
// 遍历
controls.forEach(function (item) {
    sc[item.id] = item.getValue();
});

為何寫法一存在記憶體洩漏,而寫法二不存在?

伊谢尔伦伊谢尔伦2747 天前650

全部回覆(1)我來回復

  • 迷茫

    迷茫2017-05-19 10:24:13

    並不一定是內存洩漏,還有可能是gc 沒有進行回收,第一種寫法中語句沒有結束,需要對所有的dom 保持引用,而第二點上一個語句結束,有可能gc 進行了回收dom節點,單純從你測試的次數和時間上不能確定是否第一種寫法是不是真的dom 最終不會回收。

    你應該對比15.9 和15.6 這兩次的數據,在表格的左上角有一個comparison ,就是你圖中的summary 的部分,對比一下15.9 和15.6 究竟多了什麼,點開看看黃色的部分,代表持續引用。再假如運行運行多次記憶體仍然不減少,才能判斷為記憶體洩漏。

    回覆
    0
  • 取消回覆