zoukankan      html  css  js  c++  java
  • 关于JavaScript内存泄漏的质疑

         近几天看了些关于JavaScript内存管理的文章,相对于Java JVM的内存管理,显得简单些。

         在学习的过程中,发现有不少网友谈到了循环引用,说循环引用会造成内存泄漏,垃圾回收器无法回收。

         实际上,并没有这么可怕,根据小菜目前的了解,这种循环引用造成的内存泄漏,仅仅会发生在低版本的IE浏览器上,现代浏览器是不会这么蠢的。

         举个例子,网络上流行的说法大致有如下两种:

     1 <!DOCTYPE html>
     2 <html>
     3   <head>
     4     <meta charset="utf-8">
     5     <meta name="viewport" content="width=640, initial-scale=0.5, user-scalable=no" />
     6     <title>循环引用内存分析</title>
     7     <style>
     8     </style>
     9   </head>
    10   <body>
    11     <input type="button" onclick="Problem();" value="call Problem">
    12     <input type="button" onclick="MyBindEvent();" value="call MyBindEvent">
    13   </body>
    14   <script>
    15     //闭包引起的隐式循环引用
    16     function MyBindEvent(){
    17       var obj=document.createElement("div");
    18       obj.onclick=function(){
    19         //Even if it's a empty function
    20       };
    21     }
    22 
    23     //显式循环引用
    24     function Problem() {
    25       var objA = new Object();
    26       var objB = new Object();
    27 
    28       objA.someOtherObject = objB;
    29       objB.anotherObject = objA;
    30     }
    31   </script>
    32 
    33 </html>

         一个简单的页面,上边两个按钮,分别调用两个会造成内存泄漏的方法。

         借助于Chrome浏览器的Profiles功能,生成内存快照,然后对比,发现这两种写法在谷歌浏览器下均没有泄漏问题。

         具体做法是:

    1. 打开页面不做任何操作,直接生成页面内存快照。
    2. 点击按钮,然后再次生成内存快照。
    3. 对比两次内存变化。

         不断重复这个过程,生成7、8个快照,趋于稳定,会发现往后内存根本没有变化。

     

         每次生成快照之前,都会强制执行GC(垃圾回收),说明我们每次构造的循环引用,马上被回收了,所以不会出现在快照中。

         接下来从理论角度说说为什么应该被回收。

         因为这些循环引用,说白了都是无效引用。可以简单理解为:只有从栈区发起的引用才是有效的。本例中的引用,是堆区对象的互相引用,虽然引用计数不为0,但是不可到达,在回收内存时直接就被消灭了。

         再深入了说,低版本IE浏览器采用的是引用计数机制回收内存,互相引用造成对方计数互不为0,导致无法回收。

         而现代浏览器,采用的是Cheney算法,大致就是把内存分为两份,不断的来回复制,这样那些不可到达的对象,就无法复制,自然被回收了。

         栈区、静态、常量之类的字眼,一般是代表root(根)区,只有从这些地方发出的引用,才是可到达的,有效的。

  • 相关阅读:
    spring boot 报错 Failed to read HTTP message
    spring boot 之 Mybatis 配置
    Java生成xlsx格式的excel文件
    遍历FTP目录及下载
    Spring 报错
    git ssh key生成
    spring mvc原理
    LightOJ 1154
    Light OJ 1153
    入栈出栈的顺序问题
  • 原文地址:https://www.cnblogs.com/iyangyuan/p/4310601.html
Copyright © 2011-2022 走看看