内存泄漏与垃圾回收机制

什么是内存泄漏?

程序的运行需要内存,只要程序提出要求,操作系统或者运行是就必须供给内存。对于持续运行的服务进程,必须及时释放内存,否则,内存占用越来越高,轻则影响系统性能,重则导致进程崩溃。不再用到的内存,没有及时释放,就叫做内存泄漏。

有些语言(比如c语言)必须手动释放内存,程序员负责内存管理。这很麻烦,所以大多数语言提供自动内存管理,减轻程序员的负担,这被称为"垃圾回收机制"。

标题常见的内存泄漏的原因

全局变量引起的内存泄漏

  function leaks(){
    
      
    leak = 'xxxxxx';//leak 成为一个全局变量,不会被回收
}

闭包引起的内存泄漏

var leaks = (function(){
    
      
    var leak = 'xxxxxx';// 被闭包所引用,不会被回收
    return function(){
    
    
        console.log(leak);
    }
   })()

dom清空或删除时,事件未清除导致的内存泄漏

<div id="container">
</div>
 $('#container').bind('click', function(){
    
    
    console.log('click');
}).remove();  
// zepto 和原生 js下,#container dom 元素,还在内存里jquery 的 empty和 remove会帮助开发者避免这个问题  
<div id="container">  
</div>
$('#container').bind('click', function(){
    
    
    console.log('click');
}).

把事件清除了,即可从内存中移除

javascript垃圾回收机制原理

解决内存的泄露,垃圾回收机制会定期(周期性)找出那些不再用到的内存(变量),然后释放其内存。现在各大浏览器通常采用的垃圾回收机制有两种方法:标记清除,引用计数。

必要性:由于字符串、对象和数组没有固定大小,所有当他们的大小已知时,才能对他们进行动态的存储分配。JavaScript程序每次创建字符串、数组或对象时,解释器都必须分配内存来存储那个实体。只要像这样动态地分配了内存,最终都要释放这些内存以便他们能够被再用,否则,JavaScript的解释器将会消耗完系统中所有可用的内存,造成系统崩溃。

1、标记清除

这是javascript中最常用的垃圾回收方式。当变量进入执行环境是,就标记这个变量为“进入环境”。大部分浏览器以此方式进行垃圾回收,当变量进入执行环境(函数中声明变量)的时候,垃圾回收器将其标记为“进入环境”,当变量离开环境的时候(函数执行结束)将其标记为“离开环境”,在离开环境之后还有的变量则是需要被删除的变量。标记方式不定,可以是某个特殊位的反转或维护一个列表等。
垃圾收集器给内存中的所有变量都加上标记,然后去掉环境中的变量以及被环境中的变量引用的变量的标记。在此之后再被加上的标记的变量即为需要回收的变量,因为环境中的变量已经无法访问到这些变量。

2、引用计数

另一种不太常见的垃圾回收策略是引用计数。这种方式常常会引起内存泄漏,低版本的IE使用这种方式。机制就是跟踪一个值的引用次数,当声明一个变量并将一个引用类型赋值给该变量时该值引用次数加1,当这个变量指向其他一个时该值的引用次数便减一。当该值引用次数为0时就会被回收。

猜你喜欢

转载自blog.csdn.net/zzDAYTOY/article/details/108568681
今日推荐