垃圾收集

学习每一种语言都要学习垃圾回收,才能码出性能强的代码。但是现在学这些东西,感觉到很困惑。那有什么办法。
javascript是一门具有自动垃圾收集机制的编程语言,开发人员不用关心内存分配和回收问题。
javascript具有自动垃圾收集机制,也就是说执行环境会管理代码执行使用的内存情况。C语言和C++之类的语言开发人员的一项重要工作就是手工跟踪内存的使用情况。javascript开发人员不用再关心内存的使用问题,内存的分配及回收完全实现自动管理。原理很简单,找到不用的变量,释放其占用的内存就可以。可以按固定的时间间隔或设定时间间隔周期性地执行回收这一操作。
局部变量的正常生命周期:函数执行过程中存在,执行中会为变量分配相应的栈或堆内存。执行完函数后,变量所占的内存就是垃圾,就要清理。垃圾收集器会标记这些无用的内存,到了清理时间就清理。不同的浏览器会有不同的无用变量标记方法。
本文目录

  • 标记清除
  • 引用计数
  • 性能问题
  • 管理内存

标记清除

标记清除是javascript最常用的垃圾收集方式。当进行执行环境时,对执行环境中的所有变量标记为进入环境,逻辑上讲是不能清除标记为进入环境的变量的。离开环境后就标记为离开环境,垃圾收集机制就是清除这部分。不同的浏览器用不同的方法标记,不同浏览器的清除的间隔也不同。这些问题太复制了,看不懂……

引用计数

引用计数方法不常用。用引用计数的方法来记录变量引用的次数,被引用就加1,断开引用就减1,直到引用次数为0就代码待清除。
这里有一个问题,如果有两个变量相互引用的话,那就永远成不了垃圾了,这是它的不好处,所以这种方式不好。
所以对不用的引用变量,我们最好手动地为其赋值为null来释放其引用,这叫——解除引用

性能问题

这里垃圾回收而引发的性能问题,IE浏览器就最显著,IE浏览器垃圾收集器根据内存的分配量来决定运行的,满足256个变量、4096个对象(数组/字面量/数组元素)或者64KB的字符串中任何一个临界值,就运行垃圾回收。如果一个脚本一直没有达到这个临界值,那就永远不回收,如果非垃圾变量一直有这个值就一直执行垃圾回收。结果性能就很差,IE7就重写了其垃圾回收例程。
触发垃圾回收:
在IE中,window.CollectGarbage()方法会立即执行收集。
Opera7用window.opera.collect()方法也会启动垃圾收集例程。
但不建议这么干。

管理内存

使用具备垃圾收集机制语言编写程序时,开发人员一般不用操心内存管理。但是javascript还是有点特别的,主要问题是——分配给web浏览器的可用内存通常比分配给桌面应用程序的少。这么做是出于安全考虑,防止不好的javascript代码耗尽内存导致系统崩溃。内存的限制导致变量得到的内存少,还会影响调用栈以及在一个线程中能够同时执行的语句数量。
所以,确保占用最少内存可以让页面性能更好。优化性能最佳方式是用解除引用的方法,这一做法适用于大多数全局变量和全局对象的属性,局部的会在离开执行环境时自动解除引用了。
解除一个值的引用并不是说自动回收该值的内存了,只是让该值脱离执行环境,以便垃圾收集机制在下次运行时回收。

总结

  1. 标记清除是最常用的垃圾收集策略,这种算法的思想是给当前不使用的值加上标记,然后再回收其内存。
  2. 引用计数也是一种收集策略,这种算法的思想是跟踪记录所有被引用的次数。javascript引擎目前都不再使用这种算法,但是在IE中访问非原生javascript对象(如DOM元素)时,这种算法仍然可能会导致问题。
  3. 当代码中存在循环引用现象时,“引用计数”算法就会导致问题。
  4. javascript开发人员应该怎么管理内存呢。
  5. 离开作用域的值将被标记为可回收,因此在垃圾回收期间被删除。
  6. 解除变量不仅有助于消除循环引用现象,而且对垃圾收集也有好处。为了确保有效地回收内存,应该及时解除不再使用的全局对象、全局对象属性以及循环引用变量的引用。

最后更新: 2017年12月14日 17:41

原始链接: http://allen.men/2017/03/29/garbage/

× 收钱就是兴奋
打赏二维码