JavaScript垃圾回收与内存泄露

简介: 内存泄露是一个非常重要的一个问题,特别是对于JavaScipt,如果占用内存过大,将使整个浏览器的速度拖慢,造成一个很不好的用户体验。 内存泄露造成的原因在于没有及时的进行垃圾回收,或者只要页面存在,就不会进行垃圾回收。

内存泄露是一个非常重要的一个问题,特别是对于JavaScipt,如果占用内存过大,将使整个浏览器的速度拖慢,造成一个很不好的用户体验。

内存泄露造成的原因在于没有及时的进行垃圾回收,或者只要页面存在,就不会进行垃圾回收。例如全局变量等等。

首先了解一下,关于垃圾回收机制,分为两种,标记清除法和引用计数法。

标记清除法,一个函数局部作用域,当这个函数调用的时候,内部定义的局部变量将进入运行环境。当函数调用完毕之后,这个变量就会被标记,当下一次垃圾清除的时候,一起删除。

引用计数法引用计数的含义是跟踪记录每个值被引用的次数。当声明一个变量并将一个引用类型值赋给该变量时,则这个值的引用次数便是1,如果同一个值又被赋给另 一个变量,则该值的引用次数加1,相反,如果包含对这个值引用的变量又取得了另一个值,则这个值的引用次数减1。当这个值的引用次数为0时,说明没有办法 访问到它了,因而可以将其占用的内存空间回收。(JavaScript 高级程序设计第二版)。当退出作用域的时候,然后减1;

然后我们来看一下,内存分配方式。

静态分配:全局变量,函数之类的分配方式,由于他们页面没有关闭之前,他们是不会被清除的。

自动分配:局部变量,但不是所有局部变量,比如说自带的类型,只要不是动态分配的局部变量就是自动分配的。满足两个条件,

动态分配:使用new创建出来的,主动要求给分配空间的。

我们谈一下,内存泄露常见的一些地方吧,基本上都是引用计数法搞的。

1:相互引用/循环引用

[javascript] view plain copy print ?
  1.             function A()  
  2.             {  
  3.                 this.b;  
  4.             }  
  5.             function B()  
  6.             {  
  7.                 this.a;  
  8.             }  
  9.             var a=new A();  
  10.             var b=new B();  
  11.             a.b=b;  
  12.             b.a=a;  
  13.           
  14.           

这样的结果是什么,当然是a,b的技术永远也不会变成0。所以说,当我们不需要的时候,解引用。添加上下面两句。
[javascript] view plain copy print ?
  1. a.b=null;  
  2.             b.a=null;  
a.b=null; b.a=null;
我们这里只是举了两个对象,当三个甚至更多的时候,更要注意。

2:自引用

[javascript] view plain copy print ?
  1.             function A()  
  2.             {  
  3.                 this.a;  
  4.             }  
  5.             var a=new A();  
  6.             a.a=a;  
  7.           
解决办法和上面的一样,解引用

3:事件绑定

一般来说,事件绑定是没有多少问题的。但是问题在于,如果你把这个DOM移除了,但是之前的事件监听仍然还在内存之中,之后就无法消除这个泄露问题了。

解决办法,就是在DOM移除之前就需要把这个事件绑定给移除掉。

4:闭包

[javascript] view plain copy print ?
  1. function leak(){  
  2.                var o = {};  
  3.                function closure(){  
  4.                }  
  5.                o.f = closure;  
  6.            }  
function leak(){ var o = {}; function closure(){ } o.f = closure; }

我们从上面图上可以看出来,leak里面引用这o,而o.f引用closure,closure的环境位于leak,这就变成一个相互引用。对于这个东西来说,就要把函数放到外面来。

总体来说,如果减少内存泄露的话,就尽量减少相互引用,没有用的时候解引用,不要一直占据这内存。

并不是你关闭了这个页面或者页面跳转,内存泄露就不存在了,除非你关闭了整个浏览器

下面有两个小工具,用来检测内存泄露问题

SIEve http://ishare.iask.sina.com.cn/f/17304467.html

Leak Monitor https://addons.mozilla.org/zh-CN/firefox/addon/leak-monitor/

目录
相关文章
|
1月前
|
JavaScript 前端开发 算法
Java Script 中的垃圾回收机制有哪些缺点
Java Script 中的垃圾回收机制有哪些缺点
13 0
|
1月前
|
JavaScript 前端开发 算法
描述 JavaScript 中的垃圾回收机制。
描述 JavaScript 中的垃圾回收机制。
17 1
|
1月前
|
Java 程序员
探讨JVM垃圾回收机制与内存泄漏
探讨JVM垃圾回收机制与内存泄漏
|
3月前
|
存储 算法 Java
理解JVM的内存模型和垃圾回收算法
理解JVM的内存模型和垃圾回收算法
43 2
|
3天前
|
存储 缓存 监控
Java内存管理:垃圾回收与内存泄漏
【4月更文挑战第16天】本文探讨了Java的内存管理机制,重点在于垃圾回收和内存泄漏。垃圾回收通过标记-清除过程回收无用对象,Java提供了多种GC类型,如Serial、Parallel、CMS和G1。内存泄漏导致内存无法释放,常见原因包括静态集合、监听器、内部类、未关闭资源和缓存。内存泄漏影响性能,可能导致应用崩溃。避免内存泄漏的策略包括代码审查、使用分析工具、合理设计和及时释放资源。理解这些原理对开发高性能Java应用至关重要。
|
6天前
|
存储 前端开发 安全
JVM内部世界(内存划分,类加载,垃圾回收)(上)
JVM内部世界(内存划分,类加载,垃圾回收)
33 0
|
1月前
|
JavaScript 前端开发 Java
JavaScript的垃圾回收机制
JavaScript的垃圾回收机制
23 1
|
1月前
|
Java 程序员 Python
|
2月前
|
监控 Java 编译器
优化Go语言程序中的内存使用与垃圾回收性能
【2月更文挑战第5天】本文旨在探讨如何优化Go语言程序中的内存使用和垃圾回收性能。我们将深入了解内存分配策略、垃圾回收机制,并提供一系列实用的优化技巧和建议,帮助开发者更有效地管理内存,减少垃圾回收的开销,从而提升Go程序的性能。
|
3月前
|
前端开发 JavaScript 算法
JavaScript 内存管理的秘密武器:垃圾回收(下)
JavaScript 内存管理的秘密武器:垃圾回收(下)
JavaScript 内存管理的秘密武器:垃圾回收(下)