转《js闭包与内存泄漏》
首先,能导致内存泄漏的一定是引用类型的变量,比如函数和其他自定义对象。而值类型的变量是不存在内存泄漏的,比如字符串、数字、布尔值等。
因为值类型是靠复制来传递的,而引用类型是靠类似c语言中的指针来传递的。
可以认为一个引用类型的变量就是一个指向某个具体的内存地址的指针。
当我们用js代码创建一个引用类型的时候(以下简称对象),js引擎会在内存中开辟一块空间来存放数据,并把指针引用交给那个变量。内存是有限的,js引擎必须保证当开辟的对象没用的时候,把所分配的内存空间释放出来,这个过程叫做垃圾回收,负责回收的叫做垃圾回收器(GC)。
OK,内存泄漏是指我们已经无法再通过js代码来引用到某个对象,但垃圾回收器却认为这个对象还在被引用,因此在回收的时候不会释放它。导致了分配的这块内存永远也无法被释放出来。如果这样的情况越来越多,会导致内存不够用而系统崩溃。
不可控的东西才是最可怕的!
最经典的例子就是外部我们不可控的引用。比如说IE6中dom对象引用了js对象,而dom对象在某个时刻被移除掉了,但js引擎不知道它被移除掉,还傻傻的保留着引用呢,就不会把js对象释放。(ie7+改善很多了,我不是黑IE)
然后就是闭包中的引用了。咱们使用闭包的目的,就是要保存内部变量的状态以便我们哪个时候去通过闭包使用它作用域内的变量。
我们可以把闭包形象的理解为一道门,屋子里面是内部变量。钥匙是一个引用。
当我们把钥匙给张三这个对象(otherObject1.p1 -> 门),产生了一个引用
当我们再配一把钥匙给李四这个对象(otherObject2.p2 -> 门)产生了另外一个引用
GC在回收的时候会判断一个闭包还有没有人拿着钥匙,要是没有引用或者是内部循环引用(李四在屋子里),就会释放闭包内变量所在的空间,回收垃圾
我斗胆的说一句:严格意义上讲,闭包不是真正产生内存泄漏的原因!各位有意见可以评论里指出,现在举个最简单的例子:
function bindEvent()
{
var obj = document.createElement("XXX");
obj.onclick = function(){
// ...
}
}
bindEvent();
这人把钥匙(引用)给了一个外部不可控的dom对象,怎么能怪人家闭包的错误呢!
再看下面代码:
var otherJsObj = {};
function bind()
{
otherJsObj.func1 = function(){
// ...
}
}
bind();
我把钥匙给了otherJsObj。然后叮嘱它:“你不用的时候就把你的func1置空或者赋值成别的对象,解除我的引用,我好回收垃圾”。这样可控,因为咱们都是自己人(js对象),有访问权限[呵呵]
楼主会产生这样的困惑,是因为闭包确实是在保持对别的对象的引用。也会产生较大的内存占用。但这是可控制的,不是闭包的错。
转《js闭包与内存泄漏》的更多相关文章
- 转《在浏览器中使用tensorflow.js进行人脸识别的JavaScript API》
作者 | Vincent Mühle 编译 | 姗姗 出品 | 人工智能头条(公众号ID:AI_Thinker) [导读]随着深度学习方法的应用,浏览器调用人脸识别技术已经得到了更广泛的应用与提升.在 ...
- face-api.js:一个在浏览器中进行人脸识别的 JavaScript 接口
Mark! 本文将为大家介绍一个建立在「tensorflow.js」内核上的 javascript API——「face-api.js」,它实现了三种卷积神经网络架构,用于完成人脸检测.识别和特征点检 ...
- TensorFlow.js之安装与核心概念
TensorFlow.js是通过WebGL加速.基于浏览器的机器学习js框架.通过tensorflow.js,我们可以在浏览器中开发机器学习.运行现有的模型或者重新训练现有的模型. 一.安装 ...
- 在Java中直接调用js代码(转载)
http://blog.csdn.net/xzyxuanyuan/article/details/8062887 JDK1.6版添加了新的ScriptEngine类,允许用户直接执行js代码. 在Ja ...
- 第十一章:WEB浏览器中的javascript
客户端javascript涵盖在本系列的第二部分第10章,主要讲解javascript是如何在web浏览器中实现的,这些章节介绍了大量的脚本宿主对象,这些对象可以表示浏览器窗口.文档树的内容.这些章节 ...
- 在Java中直接调用js代码
JDK1.6版添加了新的ScriptEngine类,允许用户直接执行js代码. 在Java中直接调用js代码 不能调用浏览器中定义的js函数,会抛出异常提示ReferenceError: “alert ...
- TensorFlow.js入门(一)一维向量的学习
TensorFlow的介绍 TensorFlow是谷歌基于DistBelief进行研发的第二代人工智能学习系统,其命名来源于本身的运行原理.Tensor(张量)意味着N维数组,Flow(流)意味着 ...
- JavaScript权威指南--WEB浏览器中的javascript
知识要点 1.客户端javascript window对象是所有客户端javascript特性和API的主要接入点.它表示web浏览器的一个窗口或窗体,并且可以用window表示来引用它.window ...
- 解决webkit浏览器中js方法中使用window.event提示未定义的问题
这实际上是一个浏览器兼容性问题,根源百度中一大堆,简要说就是ie中event对象是全局变量,所以哪里都能使用到,但是webkit内核的浏览器中却不存在这个全局变量event,而是以一个隐式的局部变量的 ...
- JS Date当前时间:获取日期时间方法在各浏览器中的差异
转自:http://www.feiesoft.com/00047/<script type="text/javascript"> // JS Date当前时间获取方法在 ...
随机推荐
- js == 与 === 的区别[转]
we文章转自http://blog.sina.com.cn/s/blog_4b32835b01014iv9.html 1.对于string,number等基础类型,==和===是有区别的 1)不同类型 ...
- [转]Qt 之 QFileSystemWatcher
简述 QFileSystemWatcher类用于提供监视文件和目录修改的接口. QFileSystemWatcher通过监控指定路径的列表,监视文件系统中文件和目录的变更. 调用addPath()函数 ...
- 如何使用Simulink模糊控制
在用这个控制器之前,需要用readfis指令将fuzzy1.fis加载到matlab的工作空间,比如我们用这样的指令:fis1=readfis(‘fis1.fis’):就创建了一个叫myFLC的结构体 ...
- python基础学习第五天
li=[1,2,33,-1,'dbssd',[4,5,6],{4:'rfw',5:'re'}]del(li[1])print(li)print(type(li))#访问元素print(li[0])pr ...
- JAVA体系的线程的实现,线程的调度,状态的转换
java体系中线程的实现 1.使用内核线程实现 内核线程就是直接由操作系统内核支持的线程,这种线程由内核来完成线程切换,内核通过操作调度器对线程进行调度,并负责将线程的任务映射到各个处理器上,每个内核 ...
- TCP/IP协议---ARP协议
ARP协议 以下就默认在以太网类型的网络. 这个协议的作用是通过ip地址(32bit)找到硬件地址(48bit).顺便提一下:在一个局域网里,大家常见的设备交换机,交换机上的主机在互相通信时,实际用的 ...
- 创建一个Scalar-valued Function函数来实现LastIndexOf
昨天有帮助网友解决的个字符串截取的问题,<截取字符串中最后一个中文词语(MS SQL)>http://www.cnblogs.com/insus/p/7883606.html 虽然实现了, ...
- Java8中的HashMap分析
本篇文章是网上多篇文章的精华的总结,结合自己看源代码的一些感悟,其中线程安全性和性能测试部分并未做实践测试,直接是“拿来”网上的博客的. 哈希表概述 哈希表本质上一个数组,数组中每一个元素称为一个箱子 ...
- KMeans算法分析以及实现
KMeans KMeans是一种无监督学习聚类方法, 目的是发现数据中数据对象之间的关系,将数据进行分组,组内的相似性越大,组间的差别越大,则聚类效果越好. 无监督学习,也就是没有对应的标签,只有数据 ...
- Sql_join left right
1.内连接inner join 只返回两张表中所有满足连接条件的行,即使用比较运算符根据每个表中共有的列的值匹配两个表中的行.(inner关键字是可省略的) ①传统的连接写法: 在FROM子句中列出所 ...