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/

目录
相关文章
|
10天前
|
JavaScript 前端开发 算法
JS垃圾回收机制
JS垃圾回收机制
|
14天前
|
存储 算法 Java
Java的内存模型与垃圾回收机制
Java的内存模型与垃圾回收机制
|
26天前
|
存储 Java 程序员
【Python 的内存管理机制专栏】深入解析 Python 的内存管理机制:从变量到垃圾回收
【5月更文挑战第18天】Python内存管理关乎程序性能与稳定性,包括变量存储和垃圾回收。变量存储时,如`x = 10`,`x`指向内存中值的引用。垃圾回收通过引用计数自动回收无引用对象,防止内存泄漏。了解此机制可优化内存使用,避免循环引用等问题,提升程序效率和稳定性。深入学习内存管理对成为优秀Python程序员至关重要。
【Python 的内存管理机制专栏】深入解析 Python 的内存管理机制:从变量到垃圾回收
|
28天前
|
JavaScript 前端开发 算法
垃圾回收:JavaScript内存管理的利器
垃圾回收:JavaScript内存管理的利器
|
28天前
|
Web App开发 监控 前端开发
深入理解JavaScript内存泄漏:原因与解决方法
深入理解JavaScript内存泄漏:原因与解决方法
|
28天前
|
存储 算法 Java
Java一分钟之-Java内存模型与垃圾回收机制概览
【5月更文挑战第16天】本文简述Java内存模型(JMM)和垃圾回收(GC)机制。JMM包括栈、堆、方法区、程序计数器和本地方法栈。GC负责回收不再使用的对象内存,常用算法有新生代、老年代和全堆GC。文章讨论了内存溢出、死锁和GC性能等问题,提出了解决方案,如调整JVM参数和优化GC策略。此外,还强调了避免内存泄漏、大对象管理及正确释放资源的重要性。理解这些概念有助于提升Java应用的性能和稳定性。
28 1
|
29天前
|
缓存 自然语言处理 JavaScript
JavaScript内存泄漏导致应用性能下降,常见于闭包使用不当
【5月更文挑战第14天】JavaScript内存泄漏导致应用性能下降,常见于闭包使用不当。闭包能记住并访问词法作用域,若函数返回后,其引用的对象未被释放,就会引发泄漏。例如,`createLeakyFunction`创建的闭包保留了对大型对象`someLargeObject`的引用,即使函数执行完毕,对象也无法被垃圾回收。避免泄漏的方法包括及时解除引用、清除事件监听器、使用WeakMap和WeakSet以及定期清理缓存。使用性能分析工具可检测和修复内存泄漏问题。
25 3
|
29天前
|
监控 算法 Java
Python内存管理与垃圾回收机制
【5月更文挑战第12天】了解Python内存管理与垃圾回收对编写高效稳定程序至关重要。Python自动管理内存,使用`malloc()`和`free()`分配和释放。引用计数跟踪对象引用,当引用计数为零时对象销毁。垃圾回收处理循环引用,采用分代回收算法。优化技巧包括避免循环引用、显式释放对象、使用生成器和迭代器。理解这些机制有助于避免内存泄漏,提高性能。通过示例代码,学习如何在实践中应用内存管理最佳实践和高级优化技巧,以及如何调试和诊断内存问题。在并发和异步编程中,需注意线程安全和异步内存管理。掌握这些知识能提升Python编程的效率和质量。
23 3
|
29天前
|
JavaScript 前端开发 算法
JavaScript的垃圾回收机制通过标记-清除算法自动管理内存
【5月更文挑战第11天】JavaScript的垃圾回收机制通过标记-清除算法自动管理内存,免除开发者处理内存泄漏问题。它从根对象开始遍历,标记活动对象,未标记的对象被视为垃圾并释放内存。优化技术包括分代收集和增量收集,以提升性能。然而,开发者仍需谨慎处理全局变量、闭包、定时器和DOM引用,防止内存泄漏,保证程序稳定性和性能。
26 0
|
29天前
|
JavaScript 前端开发 算法
JavaScript 的垃圾回收机制有一些潜在的缺点
【5月更文挑战第11天】JavaScript 的垃圾回收机制虽自动化管理内存,降低泄漏风险,但也存在性能开销、无法精确控制内存释放、全局变量和闭包可能导致内存泄漏、弱引用及循环引用问题。开发者需注意优化代码,避免这些问题,以充分利用垃圾回收机制并提升应用性能。
16 0