【JavaScript】JS中的内存管理

一、JS的内存空间

JS的内存空间分为栈、堆和池。

栈中存放的一般是简单的数据,便于提升查找的效率。

而由于大部分对象这样的复杂值,它们的大小会改变,因此会存储在堆中,否则会降低变量的查询效率,此时栈中存放的是指向对象的地址。

池一般存储常量值,也会放在栈中。

JS中的基础数据类型都会放在栈中。

二、JS的垃圾回收

1、初始算法:引用计数

给对象加上一个引用计数器,如果存在其他对象对它的引用,则计数器不为0。反之,当计数器为0时,则下次垃圾回收时会将该对象看作可回收的对象。

缺点:无法解决循环引用的问题。

function cycle() {
    var o1 = {};
    var o2 = {};
    o1.a = o2;
    o2.a = o1; 

    return "Cycle reference!"
}

cycle();

优点:速度快

2、使用根对象I(比如window)遍历的方式确定引用关系,进行垃圾回收

以根对象作为一条可达链的根节点,根据引用关系往下遍历。

比如右边的三个对象,虽然存在互相引用的关系,但是并没有与根节点相连


谷歌浏览器中的标记--清除算法及标记-复制、标记-整理算法

在谷歌浏览器中,JS的堆同样会被V8引擎分为新生代和老年代,在新生代中采用标记-复制算法,老年代中采用标记-清除、标记-整理算法。

对下一次回收中可以进行回收的对象进行标记,在垃圾回收时清空这部分内存。

这里引用我的一篇博客来说明这些的概念。

https://blog.csdn.net/qq_43710345/article/details/105486320

然而IE低版本依然采用引用计数的方式,并且IE-8中的DOM对象也是,IE-9才换成了现在的算法。因此在对象不使用以后,为了适应这部分浏览器,应该结束对象的引用关系(特别是比较大的对象,因为浏览器的内存有限)。

DOM对象的循环引用
function f(){
    var element = document.getElementById('some_element');
    var myObject = new Object();
    myObject.element = element;
    element.someObject = myObject;
}
f()
var obj = {name: 'an object', age: 1000};
...
使用过程
...
obj=null;

垃圾回收时是按照临界值来划分的,在IE7中,如果垃圾收集例程回收的内存分配量低于15%,则变量、字面量和数组元素的临界值就会加倍。如果例程回收了85%的内存分配量,则将各种临界值重置回默认值。这样,极大地提升了IE在运行包含大量javascript的页面时的性能。

除了自动垃圾回收,我们也可以进行手动的垃圾回收,比如,在IE中可以调用window.CollectGarbage()方法来进行,但是不建议这么做。

三、内存管理中的问题

内存泄漏(没有及时释放内存)

原因:

1、缓存:缓存有助于数据的快捷复用,然而缓存无法回收,如果突破上限则有可能导致内存泄漏

2、全局变量定义的不规范,比如下面的代码,可能只是想定义局部变量,但是没有使用var/let等来定义。

function foo(arg) {
    bar = "this is a hidden global variable";
}

内存溢出(空间不够用)

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值