文档章节

JavaScript 的垃圾回收与内存泄露

smalldragonluo
 smalldragonluo
发布于 2014/06/16 23:33
字数 769
阅读 1570
收藏 0

    JavaScript采用垃圾自动回收机制,运行时环境会自动清理不再使用的内存,因此javascript无需像C++等语言一样手动释放无用内存。

    在这之前先说一下垃圾回收的两种方式:引用计数标记清除

    引用计数方式会为每个已分配内存单元设置计数器,当计数器减少到0的时候就意味着该单元无法再被引用,将会被清除。

    有一个问题是,当存在循环引用时,内存单元的计数器将永远不为0,内存的释放会比较复杂(需要使用到弱引用)。

obj.val = obj2;
obj2.val = obj;

 

    标记清除式维护一条链表,当变量进入scope时被加入这条链表,移出scope时被从链表剔除。当gc被激活时,首先为每个变量打上一个标记,然后清除存在于那条链表的变量的标记以及变量引用的成员的标记。最后,不再使用到的变量仍旧被gc标记着,将被释放,包括循环引用。

    如果一段不再使用的内存未得到回收,将导致内存泄露 它将一直占据着内存而无法被利用,可能造成系统运行缓慢,浏览器崩溃等问题。

    关于浏览器的javascript实现使用哪种回收机制,众说纷纭,感觉贵圈好乱。

    我google了一下,http://www.ibm.com/developerworks/web/library/wa-memleak/?S_TACT=105AGX52&S_CMP=cn-a-wa 提到IE以及火狐都使用引用计数的机制回收DOM对象, http://blogs.msdn.com/b/ericlippert/archive/2003/09/17/53038.aspx 说JScript采用 nongenerational mark-and-sweep garbage collector(一种标记清除),还有资料提到现代浏览器都使用标记清除回收javascript垃圾。

    总结为,浏览器回收JavaScript内存采用标记清除,使用引用计数回收宿主对象(如Dom、Bom、ActiveX Object)。

    根据我在IE上做的测试,javascript对象间的循环引用不会引发内存泄露。

 

setInterval(function(){
    for(var i = 0; i < 100000; i++){
        var obj = {}, obj2 = {};
        obj.val = obj2;
        obj2.val = obj;
    }
}, 10);

 

    内存使用呈周期性变化,一直稳定,看来不用担心javascript对象的循环引用问题。

    既然Dom采用引用计数回收内存,那是否存在内存泄露问题?

 

var nodeHold = [],
                 interval = setInterval(function(){
                    for(var i = 0, length = 1000; i < length; i++){
                        var node = document.createElement("div"),
                            obj = {};
                        node.val = obj;
                        obj.val = node;
                        document.body.appendChild(node);
                        document.body.removeChild(node);
                    }
            }, 500);

 

    在IE7与IE8上,内存直线上升。

    与 http://blogs.msdn.com/b/ericlippert/archive/2003/09/17/53038.aspx 所称一致,原因是javascript的垃圾回收管不了Dom对象,且Dom使用引用计数回收方式,导致循环引用无法回收。前提是Dom必须先加到文档树再删除(我猜测是为真正的Dom对象分配内存,而这不属于javascript)。

    要注意的是,IE9+并不存在循环引用导致Dom内存泄露问题,可能是微软做了优化,或者Dom的回收方式已经改变。

 

© 著作权归作者所有

共有 人打赏支持
smalldragonluo
粉丝 2
博文 9
码字总数 5320
作品 0
南岸
私信 提问
JavaScript内存管理(转)

摘抄一篇文章,写得非常好,出处在此 作为一门高级语言,JS并不像低级语言C/C++那样拥有对内存的完全掌控。JS中内存的分配和回收都是自动完成的,内存在不使用的时候会被垃圾回收器自动回收。...

Xtc丶
02/16
0
0
javascript 垃圾回收机制

随着前端业务需求的不断增多,相比以前,我们会占用更多的内存。但是内存并不是无限的,而对于那些我们不再需要的变量、对象该怎么处理呢?难道一个一个去手动释放么?其实并不需要,Javascr...

李赫feixuan
08/07
0
0
JavaScript 的内存泄露和垃圾回收

什么是内存泄露 ? 任何编程语言,在运行时都需要使用到内存,比如在一个函数中, var arr = [1, 2, 3, 4, 5]; 这么一个数组,就需要内存。 但是,在使用了这些内存之后, 如果后面他们不会再...

大灰狼的小绵羊哥哥
昨天
0
0
JavaScript 内存机制(前端同学进阶必备)

简介 每种编程语言都有它的内存管理机制,比如简单的C有低级的内存管理基元,像,。同样我们在学习JavaScript的时候,很有必要了解JavaScript的内存管理机制。 JavaScript的内存管理机制是:内...

梁音
06/01
0
0
Javascript 内存管理

简介 低级语言,比如C,有低级的内存管理基元,像malloc(),free()。另一方面,JavaScript的内存基元在变量(对象,字符串等等)创建时分配,然后在他们不再被使用时“自动”释放。后者被称为...

nerozhao
2015/06/14
0
0

没有更多内容

加载失败,请刷新页面

加载更多

降压变换器 Buck

特点 输入输出极性相同。 工作过程 在 MOS 导通时,输入电源通过 L 和 C 滤波后向负载端提供电流;当 MOS 断开后,L 通过二极管续流,保持负载电流连续。输出电压因为占空比的作用,不会超过...

colinux
今天
1
0
Apache日志不记录访问静态文件,访问日志切割,静态元素过期时间设置

Apache配置不记录访问静态文件的日志 网站大多元素为静态文件,如图片、css、js等,这些元素可以不用记录 vhost原始配置 <VirtualHost *:80> ServerAdmin test@163.com DocumentRoo...

野雪球
今天
3
0
聊聊storm的ICommitterTridentSpout

序 本文主要研究一下storm的ICommitterTridentSpout ICommitterTridentSpout storm-core-1.2.2-sources.jar!/org/apache/storm/trident/spout/ICommitterTridentSpout.java public interface......

go4it
今天
4
0
Ubuntu常用操作

查看端口号 netstat -anp |grep 端口号 查看已使用端口情况 netstat -nultp(此处不用加端口号) netstat -anp |grep 82查看82端口的使用情况 查找被占用的端口: netstat -tln netstat -tl...

hc321
昨天
4
0
网站cdn的静态资源突然访问变的缓慢,问题排查流程

1.首先我查看了一下是否自己的网络问题,通过对比其他资源的访问速度和下载速度,确认不是 2.通过ping 和 tracert 判断cdn域名能否正常访问,(最后回想感觉这一步可以省略,因为每次最终能访...

小海bug
昨天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部