技术频道导航
HTML/CSS
.NET技术
IIS技术
PHP技术
Js/JQuery
Photoshop
Fireworks
服务器技术
操作系统
网站运营

赞助商

分类目录

赞助商

最新文章

搜索

[实例]分析JS闭包如何导致内存泄漏以及如何防止它

作者:admin    时间:2022-6-3 14:48:32    浏览:

闭包一个强大优势是内部函数可以访问外部函数的变量,但是也正是这一个特征,让闭包容易产生内存泄露的负面影响。

Javascript 允许嵌套函数(函数中的函数)访问父函数的变量,内部函数访问外部函数变量的过程称为闭包。

但是一旦一个变量被任何闭包使用,它就会在该范围内所有闭包共享的词法环境中结束,这可能导致内存泄漏。

分析JS闭包如何导致内存泄漏以及如何防止它

示例

<html>
<body>
<script>
   function parentFunction(arg1) {
      var a = arg1;
      return function childFunction (arg2) {
       alert( a +" "+ arg2);
    };
   };
   var val = parentFunction("outer val");
   val("inner val");
</script>
</body>
</html>

demodownload

执行结果

在该示例中,“childFunction”是在“parentFunction”外部函数中定义的内部函数。当使用参数“outer val”调用'parentFunction'时,外部变量a被赋值为“outer val”。函数返回一个指向内部函数“childFunction”的指针,该指针包含在变量'val'中。

即使外部函数已经返回,外部函数的局部变量 a 仍然存在。在 javascript 中,在调用 parentFunction 的那一刻,将创建一个具有属性“a”的范围对象。此属性包含 arg1 的值,也称为“outer val”。同样当parentFunction返回时,它会返回内部函数(childFunction),它包含在变量val中。

由于内部函数持有对外部函数变量的引用,因此具有属性“a”的作用域对象不会被垃圾回收。

避免内存泄漏

通过添加另一个函数,将有两个内部函数。由于有两个内部函数,因此没有函数可以通过完全停止闭包来引用外部函数的变量。

当没有闭包时,内存泄漏的机会会减少。

<html>
<body>
<script>
   window.onload=function parentFunction(){
      var Obj1 = function childFunction1()
      {
         document.write("the leak is avoided");
      };
   (function childFunction2(){
      var obj2 = document.getElementById("closure");
      obj2.onclick=Obj1
      })(); //这个是立即执行函数
   };
</script>
<input type = "button" id="closure" value ="Click Here">
</body>
</html>

demodownload

执行代码后,按钮将显示如下

 

按下按钮后,我们将得到如下输出:

the leak is avoided

总结

本文通过示例,介绍了闭包如何导致内存泄漏以及如何防止它。闭包虽然功能强大,但它有一定的负面影响,所以在编程过程中,需要考虑是否真的需要用到闭包,而不用其他的处理方式。

什么是内存泄漏?

内存泄漏可以定义为一块内存不再被应用程序使用或需要,但由于某种原因没有返回给操作系统。简单来说,它是永远等待使用的被遗忘的数据。泄漏是所有问题的根源:速度减慢、崩溃、高延迟,甚至是其他应用程序的问题。

下面是内存泄漏最简单的例子。

let arr = []; 
for(let i = 5; i > 1; i++){ 
    arr.push(i-1)            // 警告!不要尝试这个
}

该示例中,我们将运行一个无限循环,不断地推入数组 i -1 直到填满我们的内存并且没有任何东西可供我们使用。在这种情况下,垃圾收集并没有真正起作用,因为我们有这个数组并且我们一遍又一遍地使用这个数组,直到程序崩溃。

相关文章

标签: 闭包  内存泄漏  
x
x
  • 站长推荐