JavaScript 内存管理

JS 内存管理

内存管理 MDN详细介绍链接

内存生命周期

分配你说需要的内存
使用分配到的内存(读,写)
不需要时将其释放\归还

JS的内存分配

值的初始化

 js 在定义变量时就完成了内存分配
 var n = 123; // 给数值变量分配内存
var s = "azerty"; // 给字符串分配内存

var o = {
  a: 1,
  b: null
}; // 给对象及其包含的值分配内存

// 给数组及其包含的值分配内存(就像对象一样)
var a = [1, null, "abra"]; 

function f(a){
  return a + 2;
} // 给函数(可调用的对象)分配内存

// 函数表达式也能分配一个对象
someElement.addEventListener('click', function(){
  someElement.style.backgroundColor = 'blue';
}, false);
通过函数调用分配内存
有些函数调用结果是分配对象内存   
var d =new Date();//分配一个Date对象
    var e = document.createElement('div');//分配一个dom元素
使用值
    使用值的过程实际上是对分配内存进行读取与写入的操作,
    读取与写入可能是写入一个变量或者一个对象的属性值,甚至传递函数的参数

当内存不再需要使用时释放
    关键在于:哪些内存什么时候不再需要
    
高级语言解释器嵌入了:
        垃圾回收器,主要工作是跟踪内存的分配和使用,以便在不需要时释放。

垃圾回收

引用

垃圾回收算法主要依赖于引用的概念,在内存管理的环境中,一个对象如果有访问
另一个对象的权限(隐式或显式),叫做一个对象引用另一个对象。
例如:一个js对象具有它原型的引用(隐式引用)和对它属性的引用(显式引用)

这里对象的概念不仅指js对象,还包括函数作用域

引用计数垃圾回收

最初级的垃圾收集算法,把“对象是否不再需要”简化定义为对象有没有其他对象
引用到他,如果零引用,对象被垃圾回收机制回收
var o = { 
  a: {
    b:2
  }
}; 
// 两个对象被创建,一个作为另一个的属性被引用,另一个被分配给变量o
// 很显然,没有一个可以被垃圾收集


var o2 = o; // o2变量是第二个对“这个对象”的引用

o = 1;      // 现在,“这个对象”只有一个o2变量的引用了,“这个对象”的原始引用o已经没有

var oa = o2.a; // 引用“这个对象”的a属性
               // 现在,“这个对象”有两个引用了,一个是o2,一个是oa

o2 = "yo"; // 虽然最初的对象现在已经是零引用了,可以被垃圾回收了
           // 但是它的属性a的对象还在被oa引用,所以还不能回收

oa = null; // a属性的那个对象现在也是零引用了
           // 它可以被垃圾回收了
限制:循环引用
    无法处理循环引用的事例
function f(){
  var o = {};
  var o2 = {};
  o.a = o2; // o 引用 o2
  o2.a = o; // o2 引用 o

  return "azerty";
}

f();
IE6,7使用引用计数方式对DOM对象进行垃圾回收,该方式常常造成对象被循环引用
时内存发生泄漏
var div;
window.onload = function(){
  div = document.getElementById("myDivElement");
  div.circularReference = div;
  div.lotsOfData = new Array(10000).join("*");
};
在上面的例子里,myDivElement 这个 DOM 元素里的 circularReference 属性引用了 myDivElement,
造成了循环引用。如果该属性没有显示移除或者设为 null,引用计数式垃圾收集器将总是且至少有一个引用,
并将一直保持在内存里的 DOM 元素,即使其从DOM 树中删去了。如果这个 DOM 元素拥有大量的数据
 (如上的 lotsOfData 属性),而这个数据占用的内存将永远不会被释放。

标记-清除算法

这个算法把”对象是否不再需要“简化定义为”对象是否可以获得“

该算法假定设置一个叫做根(root)的对象(在js中,根是全局对象)。垃圾回收器将定期
从根开始,找所有从根开始引用的对象,然后找这些对象引用的对象...从根开始
垃圾回收器将找到所有可以获得的对象和收集所有不能获得的对象

这个算法比前一个要好,因为“有零引用的对象”总是不可获得的,但是相反却不一定,参考“循环引用”。

从2012年起,所有现代浏览器都使用了标记-清除垃圾回收算法。所有对JavaScript垃圾
回收算法的改进都是基于标记-清除算法的改进,并没有改进标记-清除算法本身和它对“对象是否不再需要”
的简化定义。


循环引用不再是问题了
在上面的示例中,函数调用返回之后,两个对象从全局对象出发无法获取。因此,他们将
会被垃圾回收器回收。第二个示例同样,一旦div和其事件处理无法从根获取到,他们将会被垃圾回收器回收。

限制: 那些无法从根对象查询到的对象都将被清除
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值