首页 > 编程知识 正文

简述垃圾回收机制,js垃圾回收机制

时间:2023-05-03 10:02:47 阅读:191386 作者:289

Js 垃圾收集 局部变量的生命周期

局部变量只在函数执行的过程中存在。而在这个过程中,会为局部变量在栈(或堆)内存上分配相应的空间,以便存储它们的值。

1.1 标记清除【常见】

垃圾收集器在运行的时候会给存储在内存中的所有变量都加上标记,【其中标记形式可以使用采用任何标记方式,引自《js 高级程序设计 第三版 p79》】然后,他会去掉环境中的变量以及被环境中变量所用的变量标记,至此之后,再次被加上标记的变量将被作为预准备删除的变量,是因为环境中的无法访问到这些变量。

最后垃圾收集器完成内存清除工作,销毁那些带标记的值并回收它们所占用的内存空间。

ps:环境,【例如,在函数中声明一个变量),就将这个变量标记为“进入环境”;

1.2 引用计数【不太常见】

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

此策略会导致循环引用【对象 A 中包含一个指向对象 B 的指针,而对象 B 中也包含一个指向对象 A 的
引用】以上两个对象的引用次数都是 2。当包含此类的函数被多次调用,会导致大量内存得不到回收。

例:

var element = document.getElementById("some_element");var myObject = new Object();myObject.element = element;element.someObject = myObject;

此例一个 DOM 元素(element)与一个原生 JavaScript 对象(myObject)之间创建了循环引用,为避免这样的循环问题,可以使用以下代码清除前例的循环引用;

myObject.element = null;element.someObject = null;

将变量设置为 null 意味着切断变量与它此前引用的值之间的连接。当垃圾收集器下次运行时,就会删除这些值并回收它们占用的内存。

1.3 性能问题

如果垃圾收集例程回收的内存分配量低于15%,则变量、字面量和(或)数组元素的临界值就会加倍。如果例程回收了85%的内存分配量,则将各种临界值重置回默认值。

在IE 中,调用 window.CollectGarbage()方法会立即执行垃圾收集。在 Opera 7 及更高版本中,调用 window.opera.collect()也会启动垃圾收集例程

1.4 管理内存

确保占用最少的内存可以让页面获得更好的性能。最佳方式为:执行代码中只保存必要的数据。当数据不再有用的时候,建议通过将其值设置为null来释放其引用(此做法称为 解除引用,适用于大多数全局变量和全局对象的属性。局部变量会在它们离开执行环境时自动被解除引用);

ps: 解除一个值的引用并不意味着自动回收该值所占用的内存。解除引用的真正作用是让值脱离
执行环境,以便垃圾收集器下次运行时将其回收。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。