foreach - JavaScript连写时为什么存在内存泄漏问题?
伊谢尔伦
伊谢尔伦 2017-05-19 10:22:13
0
1
581

问题描述

在一个搜索中发现了一个内存泄露的问题,如图所示:

搜索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(); });

为何写法一存在内存泄漏,而写法二不存在?

伊谢尔伦
伊谢尔伦

小伙看你根骨奇佳,潜力无限,来学PHP伐。

全部回复 (1)
迷茫

并不一定是内存泄漏,还有可能是 gc 没有进行回收,第一种写法中语句没有结束,需要对所有的 dom 保持引用,而第二点上一个语句结束,有可能 gc 进行了回收 dom 节点,单纯从你测试的次数和时间上不能确定是否第一种写法是不是真的 dom 最终不会回收。

你应该对比 15.9 和 15.6 这两次的数据,在表格的左上角有一个 comparison ,就是你图中的 summary 的部分,对比一下 15.9 和 15.6 究竟多了什么,点开看看黄色的部分,代表持续引用。再假如运行运行多次内存仍然不减少,才能判断为内存泄漏。

    最新下载
    更多>
    网站特效
    网站源码
    网站素材
    前端模板
    关于我们 免责声明 Sitemap
    PHP中文网:公益在线PHP培训,帮助PHP学习者快速成长!