JavaScript - 垃圾回收机制

局部变量只在函数执行的过程中存在。而在这个过程中,会为局部变量在栈(或堆)内存上分配相应的空间,以便存储它们的值。然后在函数中使用这些变量,直至函数执行结束。此时,局部变量就没有存在的必要了,因此可以释放它们的内存以供将来使用。

具体实现策略

一. 标记清除

垃圾收集器在运行的时候会给存储在内存中的所有变量都加上标记(当然,可以使用任何标记方式)。然后,它会去掉环境中的变量以及被环境中的变量引用的变量的标记。而在此之后再被加上标记的变量将被视为准备删除的变量,原因是环境中的变量已经无法访问到这些变量了。最后,垃圾收集器完成内存清除工作,销毁那些带标记的值并回收它们所占用的内存空间。

二. 引用计数

  • 引用计数的含义是跟踪记录每个值被引用的次数。
  • 当声明了一个变量并将一个引用类型值赋给该变量时,则这个值的引用次数就是 1。
  • 如果同一个值又被赋给另一个变量,则该值的引用次数加 1。
  • 相反,如果包含对这个值引用的变量又取得了另外一个值,则这个值的引用次数减 1。
  • 当这个值的引用次数变成 0 时,则说明没有办法再访问这个值了,因而就可以将其占用的内存空间回收回来。这样,当垃圾收集器下次再运行时,它就会释放那些引用次数为零的值所占用的内存。

引用计数的问题:循环引用可能导致内存泄漏

function problem(){
  var obj1 = {};
  var obj2 = {};
  obj1.link2obj2 = obj2;
  obj2.link2obj1 = obj1;
}
  • 在使用标志清除策略时,当函数执行完毕,因为离开了作用域,变量obj1和obj2都会被回收。
  • 但在用引用计数策略时,由于循环引用,两个变量的计数都是2,而且没法释放(计数无法变为0)。如果函数被大量调用,会导致大量内存被占用。
  • 在IE9以下版本,IE的DOM和BOM对象使用的是C++的COM对象实现,COM就是使用引用计数策略。这导致了IE9下浏览器,在对象与DOM对象互相引用时也存在内存问题。
var element = document.getElementById("some_element");
var myObject = new Object();
myObject.element = element;
element.someObject = myObject; 
  • 消除引用
myObject.element = null;
element.someObject = null;
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 什么是垃圾回收机制? 和java,c#一样,javascript也有垃圾回收的机制,比如说c++和c就没有垃圾回收...
    我向你奔阅读 494评论 0 1
  • 为什么需要垃圾回收 由于字符串、对象和数组没有固定大小,只有当他们的大小已知时,才能对他们进行动态的存储分配。Ja...
    宇cccc阅读 1,085评论 1 0
  • 在介绍垃圾回收机制之前先了解一个概念:内存泄漏。 什么是内存泄漏? 程序的运行需要内存,只要程序提出要求,操作系统...
    前端开发_Eric阅读 282评论 0 8
  • 和C#、Java一样JavaScript有自动垃圾回收机制,也就是说执行环境会负责管理代码执行过程中使用的内存,在...
    ConRon阅读 300评论 0 0
  • 常常把“对不起”“不好意思”挂在嘴边 与别人发生分歧,往往没有底气坚持自己的观点 一出现错误总是怀疑自己,否定自己...
    可乐豆儿阅读 378评论 0 5