javascript中的内存泄漏

垃圾回收机制

JavaScript具有自动垃圾回收机制,来判断哪些变量不再需要,释放他所占的内存。

1. 变量的生命周期

在创建时,JavaScript会自动为他分配内存,然后垃圾回收机制会按照固定的时间间隔对这些变量进行评估,看他是否有效。无效则释放其内存。

2. 常见的垃圾回收方式:
  • 引用计数
    跟踪每个值被引用的次数,当引用次数为0时,回收其所占内存空间。当声明一个变量并将一个引用类型的值赋给该变量,则这个值的引用次数就是1,如果同一个值又被赋给另一个变量,该值的引用次数加1,如果包含对这个值的引用的变量又取得另一个值,这个值的引用次数减1。
    出现的问题: 循环引用,导致引用次数永远不为0,无法回收所占用的内存空间,导致内存泄漏。
    解决:手工解除循环引用,直接置为null。
    注意:IE中有一部分对象并不是原生JavaScript对象。例如,其BOM和DOM中的对象就是使用C++以COM(Component Object Model,组件对象)对象的形式实现的,而COM对象的垃圾回收器就是采用的引用计数的策略。所以IE中只要有COM对象,就会有循环引用问题。

  • 标记清除
    1.比如,当变量进入执行环境,将变量标记为“进入环境”,当变量离开环境时,将其标记为“离开环境”。我们不能释放进入环境的变量,因为有可能会用到。
    2.垃圾回收器会在运行的时候给存储在内存中的所有变量加上标记,然后去掉环境中的变量以及被环境中变量所引用的变量(闭包),在这些完成之后仍存在标记的就是要删除的变量了,因为环境中的变量已经无法访问到这些变量了,然后垃圾回收器会回收这些带有标记的变量机器所占空间。
    出现的问题:就是在清除之后,内存空间是不连续的,即出现了内存碎片,标记-整理方法可以有效地解决这个问题,整理的过程就是将不连续的内存向一端复制,使不连续的内存连续起来。

内存泄露

内存泄漏:没有及时的释放不再需要的内存。我们已经无法再通过js代码来引用到某个对象,但垃圾回收器却认为这个对象还在被引用,因此在回收的时候不会释放它。

内存泄露的形式

  • 意外的全局变量
    对未声明的变量的引用是在全局对象内创建一个新的变量
function foo(arg) {
    bar = "";
}
foo();

bar的作用域是window,所以函数foo执行完后,bar不会被回收。

  • 闭包
    闭包可以导致内存泄漏是因为内部方法保持一个对外部方法变量的引用,所以尽管方法返回了,内部方法还可以继续访问在外部方法中定义的私有变量。
    闭包经常会在不知不觉中创建出循环引用,所以它对内存泄露有不可推卸的责任
function setHandler() {
    const ele = document.getElementById('id');
    ele.onclick = function() {
        alert(ele.id);
    };
}

创建一个作为ele元素事件处理程序的闭包。而闭包又创建了一个循环引用。

  • 被遗忘的计时器或回调函数
var someResource = getData();
  setInterval(function() {
    var node = document.getElementById('Node');
    if(node) {
      node.innerHTML = JSON.stringify(someResource));
    }
  }, 1000);

setInterval 没有结束前,回调函数里的变量以及回调函数本身都无法被回收。那什么才叫结束呢?就是调用了 clearInterval。如果回调函数内没有做什么事情,并且也没有被 clear 掉的话,就会造成内存泄漏。setTiemout也会有同样的问题,需要调用clearTimeout

  • 脱离 DOM 的引用
    保存 DOM 节点内部数据结构很有用。假如你想快速更新表格的几行内容,把每一行 DOM 存成字典(JSON 键值对)或者数组很有意义。此时,同样的 DOM 元素存在两个引用:一个在 DOM 树中,另一个在字典中。将来你决定删除这些行时,需要把两个引用都清除。

参考:
https://www.ibm.com/developerworks/cn/web/wa-jsmemory/index.html
http://bubkoo.com/2015/01/31/understanding-and-solving-internet-explorer-leak-patterns/
https://jinlong.github.io/2016/05/01/4-Types-of-Memory-Leaks-in-JavaScript-and-How-to-Get-Rid-Of-Them/
https://segmentfault.com/a/1190000007616791#articleHeader4

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342

推荐阅读更多精彩内容