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

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

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

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

 <!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=640, initial-scale=0.5, user-scalable=no" />
<title>循环引用内存分析</title>
<style>
</style>
</head>
<body>
<input type="button" onclick="Problem();" value="call Problem">
<input type="button" onclick="MyBindEvent();" value="call MyBindEvent">
</body>
<script>
//闭包引起的隐式循环引用
function MyBindEvent(){
var obj=document.createElement("div");
obj.onclick=function(){
//Even if it's a empty function
};
} //显式循环引用
function Problem() {
var objA = new Object();
var objB = new Object(); objA.someOtherObject = objB;
objB.anotherObject = objA;
}
</script> </html>

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

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

具体做法是:

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

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

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

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

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

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

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

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

关于JavaScript内存泄漏的质疑的更多相关文章

  1. 一个意想不到的Javascript内存泄漏

    原文:http://point.davidglasser.net/2013/06/27/surprising-javascript-memory-leak.html 本周我在Meter的同事追踪到了一 ...

  2. Javascript内存泄漏

    Javascript内存泄漏 原文:http://point.davidglasser.net/2013/06/27/surprising-javascript-memory-leak.html 本周 ...

  3. 介绍两个非常好用的Javascript内存泄漏检测工具

    内存泄漏对开发者来说一般很难检测因为它们是由一些大量代码中的意外的错误引起的,但它在系统内存不足前并不影响程序的功能.这就是为什么会有人在很长时间的测试期中收集应用程序性能指标来测试性能. 最简单的检 ...

  4. JavaScript学习总结(二十三)——JavaScript 内存泄漏教程

    参考教程:http://www.ruanyifeng.com/blog/2017/04/memory-leak.html 一.什么是内存泄漏? 程序的运行需要内存.只要程序提出要求,操作系统或者运行时 ...

  5. JavaScript内存泄漏知多少?

    垃圾回收解放了我们,它让我们可将精力集中在应用程序逻辑(而不是内存管理)上.但是,垃圾收集并不神奇.了解它的工作原理,以及如何使它保留本应在很久以前释放的内存,就可以实现更快更可靠的应用程序.在本文中 ...

  6. JavaScript 内存泄漏教程

    一.什么是内存泄漏? 程序的运行需要内存.只要程序提出要求,操作系统或者运行时(runtime)就必须供给内存. 对于持续运行的服务进程(daemon),必须及时释放不再用到的内存.否则,内存占用越来 ...

  7. 了解 JavaScript 应用程序中的内存泄漏

    简介 当处理 JavaScript 这样的脚本语言时,很容易忘记每个对象.类.字符串.数字和方法都需要分配和保留内存.语言和运行时的垃圾回收器隐藏了内存分配和释放的具体细节. 许多功能无需考虑内存管理 ...

  8. JavaScript中的内存泄漏以及如何处理

    随着现在的编程语言功能越来越成熟.复杂,内存管理也容易被大家忽略.本文将会讨论JavaScript中的内存泄漏以及如何处理,方便大家在使用JavaScript编码时,更好的应对内存泄漏带来的问题. 概 ...

  9. How Javascript works (Javascript工作原理) (三) 内存管理及如何处理 4 类常见的内存泄漏问题

    个人总结: 1.两种垃圾回收机制: 1)引用标记算法:如果检测到一个对象没有被引用了,就清除它. ***这种算法不能处理循环引用的情况*** 2)标记—清除算法:从根(全局变量)开始向后代变量检测,任 ...

随机推荐

  1. C# 在winform或者wpf中显示控制台窗口

    这儿需要使用两个系统函数: BOOL WINAPI FreeConsole(void); //// 关闭控制台窗口,参考:http://msdn.microsoft.com/en-us/library ...

  2. ubuntu与win10互换硬盘

    实例:将sdb上的ubuntu转移至sda,将sda上的win转移至sdb1. 备份资料2. 制作老毛桃PE盘3. 格式化sda4. dd if=/dev/sdb of=/dev/sda ,将sdb克 ...

  3. C#方法中三个重要的参数:out、ref、params

    备注:适用于初学者,自学于传智播客. 1.out参数. 概念:如果在一个方法中,返回多个相同类型值的时候,可以考虑返回一数组.但是返回多个不同类型值的时候,返回数组显然不能解决问题,这时就引入out参 ...

  4. C# 模拟上传图片

    上传图片的格式一定要按规定的写,不然没办法正确上传的. 我在上传的时候就是值前面没有空一行,导致上传不成功,很纠结的错误. 我要模拟的是一个FLASH的上传控件,我开始用HttpAnalyze抓包是抓 ...

  5. 试图加载格式不正确的程序。 (异常来自 HRESULT:0x8007000B)

    两种原因: 第一种为程序的运行以平台系统位数不匹配,第二种则是该死的VS整出来的... 一般在下面三种情景下会发生. 1.64位系统上C#调用32位的C++ *.dll 2.64位系统上IIS发布含有 ...

  6. Jpanel和container和jframe的区别

    Jpanel和container和jframe的区别 (2012-05-23 19:15:11) 转载▼ 标签: 杂谈 分类: room 看到上上面的几张图,container容器是位于最高层. 下面 ...

  7. MySqlHelper

    package utils; import java.io.IOException; import java.sql.CallableStatement; import java.sql.Connec ...

  8. LeetCode(124) Binary Tree Maximum Path Sum

    题目 Given a binary tree, find the maximum path sum. For this problem, a path is defined as any sequen ...

  9. 1154. Easy sort

    #include<iostream>#include<cmath>#include<iomanip>#include<algorithm>using n ...

  10. 使用ShareSDK 时注意的问题

    1.使用ShareSDK 社会分享SDK(实现第三方登录) 1.QQ第三方登录时,如果是TencentSessionDelegate出现问题,或者是TencentApiInterface的框架出现问题 ...