JavaScript--内存管理与内存泄漏

内存管理

像 C 语言这样的底层语言一般都有底层的内存管理接口,比如 malloc() 和free() 。相反,JavaScript是在创建变量(对象,字符串等)时自动进行了分配内存,并且在不使用它们时“自动”释放。 释放的过程称为垃圾回收。这个“自动”是混乱的根源,并让JavaScript(和其他高级语言)开发者错误的感觉他们可以不关心内存管理。

因此可知 JavaScript 的内存管理使用的是 垃圾回收机制

内存生命周期

不管什么程序语言,内存生命周期基本是一致的:

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

所有语言第二部分都是明确的。第一和第三部分在底层语言中是明确的,但在像JavaScript这些高级语言中,大部分都是隐含的。

内存的回收

不再需要使用的变量也就是生命周期结束的变量,是局部变量,局部变量只在函数的执行过程中存在, 当函数运行结束,没有其他引用(闭包),那么该变量会被标记回收。
全局变量的生命周期直至浏览器卸载页面才会结束,也就是说全局变量不会被当成垃圾回收。

function fn() {
             var a={name:'lisa'};
         }
         fn();//函数调用时才给局部变量 a 分配内存空间,函数执行完毕局部变量 a 自动释放其所占内存(释放的过程称为垃圾回收),而其值即引用的对象在没有其他变量对其引用时被垃圾回收器回收

上面例子中:
函数调用时才给局部变量 a 分配内存空间,函数执行完毕局部变量 a 自动释放其所占内存(释放的过程称为垃圾回收),而其值即引用的对象在没有其他变量对其引用时被垃圾回收器回收。

垃圾回收

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

在这里,“对象”的概念不仅特指 JavaScript 对象,还包括函数作用域(或者全局词法作用域)。

垃圾回收算法包括:

  • 引用计数垃圾收集(最初级的垃圾收集算法),没有引用指向该对象(零引用),对象将被垃圾回收机制回收。
  • 标记-清除算法: 这个算法假定设置一个叫做根(root)的对象(在Javascript里,根是全局对象)。垃圾回收器将定期从根开始,找所有从根开始引用的对象,然后找这些对象引用的对象……从根开始,垃圾回收器将找到所有可以获得的对象和收集所有不能获得的对象。

从全局对象出发无法获取的对象,他们将会被垃圾回收器回收。
从2012年起,所有现代浏览器都使用了标记-清除垃圾回收算法。

引用计数垃圾收集
例子:

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属性的那个对象现在也是零引用了
           // 它可以被垃圾回收了

内存泄漏

有待总结学习,参考文章- 4类 JavaScript 内存泄漏及如何避免

参考文章:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值