JS进阶系列之内存空间
也许很多人像我一样,觉得JS有垃圾回收机制,内存就可以不管了,以至于在全局作用域下定义了很多变量,自以为JS会自动回收,直到最近,看了阮一峰老师,关于javascript内存泄漏的文章时,才发现自己写的代码,存在很严重的内存泄漏问题,再者,因为忽略对内存的学习,导致后面很多进阶概念很模糊,比如深复制与浅复制的区别,比如闭包、作用域链等等。
堆与栈
与C/C++不同,JavaScript语言没有严格意义上,区分堆与栈,所以我们可以理解为,JavaScript所有的数据都是存放在堆内存
中。
不过,在某些场景下,我们仍然需要借助堆栈数据结构来处理,所以有必要理解一下这两个数据结构的区别。
栈:也叫做堆栈
栈数据结构的一个特点就是后进先出
,好比羽毛球盒子,在一头放羽毛球,在另外一头取羽毛球。
堆数据结构,好比书架上的书,虽然已经按顺序放好了,但是我们只要知道书的名字,就可以对应的取下来,类似于JSON对象中的key-value
。
变量对象与基本数据类型
JavaScript中的数据类型大致分为,基本数据类型
与引用数据类型
,上文提到,JavaScript中所有的数据都是存放在堆内存
中,但是,这里提到的变量对象
(在执行上下文创建阶段生成),由于它有特殊的职能,所以在理解上就把它与堆内存单独分开了,如下图所示:
一般变量对象
里面存放的是基本数据类型
,包括Undefined、Null、Boolean、Number、String
,它们到是按值访问
的。
demo01
var a = 20;
var b = a;
b = 30;
console.log(a);//20
上面这段代码指的是,在变量对象中执行数据复制的时候,其实系统会自动为新的变量分配一个新的值,所以a与b其实已经是完全独立的两个变量,只是值一样而已。
堆内存与引用数据类型
javascript中的引用数据类型
是存放在堆内存
中的,但是不同于变量对象
,javascript是不允许直接访问堆内存中的数据,所以如果我们要访问引用数据类型的时候,采用的是按引用访问
,其实就是在变量对象
中存放了一个指向对象的句柄,可以理解为一个地址,要访问堆内存中的对象,就要通过这个引用句柄来访问,例如上图中的d变量,就是一个指向对象的地址。
demo02
var m = { a:10,b:20};
var n = m;
n.a = 15;
console.log(m.a);//15
上面这段代码指的是执行引用类型数据的复制时,在变量对象中会分配一个新的值,来存放新的变量,但是这两个变量的地址是一样的,相当于指向的对象是一样的,所以各自改变对象里面的属性值,会互相影响,如下图
内存泄漏
上面讲解了JavaScript中的内存空间,接下来就要讲解,我写这篇文章的初衷,就是我代码中严重的内存泄漏
内存泄漏:就是不再用到的内存,但是没有及时释放,就叫做内存泄漏
有些语言必须手动释放内存,程序员负责内存的管理,例如C语言
char *buffer;
buffer = (char*) malloc(42);
//do something with buffer
free(buffer);
这里malloc
就是负责分配内存,free
是负责释放内存。
那么JavaScript中的垃圾回收机制又是怎么一回事呢?
垃圾回收机制
以前我一直天真的以为,垃圾回收机制就像人工智能一样,会自动帮你识别出不用的内存,然后释放掉,然而真相只有一个
垃圾回收机制的原理就是,使用引用计数
法,就是语言引擎有一张“引用表”,保存了内存里面所有的资源的引用次数,就像下面这样
但是如果一个值不再需要了,引用数却不为0,垃圾回收机制是无法释放这块内存,从而导致``内存泄漏```
例如:
const arr = [1,2,3,4,5];
console.log('hello world");
arr的引用次数为1,尽管后面不再使用arr了,但是它还会持续占用内存,所以一般要这样处理
const arr = [1,2,3,4,5];
console.log('hello world");
arr = null;
让arr的指向为空,垃圾回收机制就会默认它的引用数为0而回收掉。
避免内存泄漏
在局部作用域中,等函数执行完毕,变量就没有存在的必要了,js垃圾回收机制很快做出判断并且回收,但是对于全局变量,很难判断什么时候不用,所以,经验之谈就是,尽量少使用全局变量。
我们在使用闭包的时候,就会造成严重的内存泄漏,因为闭包的原因,局部变量会一直保存在内存中,所以在使用闭包的时候,要多加小心。
JS进阶系列之内存空间的更多相关文章
- 【 D3.js 进阶系列 】 进阶总结
进阶系列的文章从去年10月开始写的,晃眼又是4个多月了,想在年前总结一下. 首先恭祝大家新年快乐.今年是羊年吧.前段时间和朋友聊天,聊到十二生肖里为什么没猫,我张口就道:不是因为十二生肖开会的时候猫迟 ...
- 【 D3.js 进阶系列 — 4.0 】 绘制箭头
转自:http://www.ourd3js.com/wordpress/?p=660 [ D3.js 进阶系列 — 4.0 ] 绘制箭头 发表于2014/12/08 在 SVG 绘制区域中作图,在绘制 ...
- 【 D3.js 进阶系列 — 1.1 】 其它表格文件的读取
CSV 表格文件是以逗号作为单元分隔符的,其他还有以制表符 Tab 作为单元分隔符的 TSV 文件,还有人为定义的其他分隔符的表格文件.本文将说明在 D3 中怎样读取它们. 1. TSV 表格文件是什 ...
- 【 D3.js 进阶系列 — 1.2 】 读取 CSV 文件时乱码的解决方法
在 D3 中使用 d3.csv 读取 CSV 文件时,有时会出现乱码问题. 怎么解决呢? 1. 乱码问题 使用 d3.csv 读取 xxx.csv 文件时.假设 xxx.csv 文件使用的是 UTF- ...
- JS进阶系列之作用域链
在之前写的进阶系列里面,提到了执行上下文在创建阶段,要创建变量对象.确定作用域链还有确定this的指向,本次将重点讲解一下作用域链. JavaScript代码的执行过程 在讲解作用域链之前,首先了解一 ...
- 【 D3.js 进阶系列 — 6.1 】 缩放的应用(Zoom)
缩放(Zoom)是另一种重要的可视化操作,主要是使用鼠标的滚轮进行. 1. zoom 的定义 缩放是由 d3.behavior.zoom() 定义的. var zoom = d3.behavior.z ...
- 【 D3.js 进阶系列 — 2.1 】 力学图的事件 + 顶点的固定
本章讨论在力学图中经常使用到的事件( Event ),然后对[p=555">进阶 - 第 2.0 章]的人物关系图进行改进.使用户可以固定拖拽的对象. 在[入门 - 第 9.2 章]和 ...
- JS进阶系列之闭包
刚刚总结完作用域链,我觉得很有必要马上对闭包总结一下,因为,之前也写过自己对闭包的理解,那时候只知道,闭包就是可以访问别的函数变量的函数,就是在函数里面的函数就叫做闭包,可是并没有深入探究,为什么,可 ...
- 【 D3.js 进阶系列 — 1.0 】 CSV 表格文件的读取
在入门系列的教程中.我们经常使用 d3.json() 函数来读取 json 格式的文件.json 格式非常强大.但对于普通用户可能不太适合,普通用户更喜欢的是用 Microsoft Excel 或 O ...
随机推荐
- js-jquery-插件开发(一)
jQuery插件开发模式 jQuery插件开发方式主要有三种:1.通过$.extend()来扩展jQuery 主要是在jQuery命名空间或者理解成jQuery身上添加了一个静态方法2.通过$.fn ...
- 使用客户端等远程连接mysql数据库
1: 远程数据库(D1)数据: 数据库用户:root,数据库密码:root,数据库ip 内网地址 192.168.100.91,数据库端口 3306 本地主机:ip 192.168.127.1 ...
- ubuntu系统下怎么安装gcc编译器
你安装一个名字叫做build-essential的软件包,就可以一次将编译器.make工具.所有的编程头文件.函数库等东东全部安装上,其中也包括gcc编译器,这是非常稳妥的安装方式,安装命令是用roo ...
- context、config
Tomcat启动时已经创建了context,并使用它读取了web.xml中的参数,后台可以从context里获取参数 后台获取参数代码: ServletContext context = getSer ...
- tf.nn.embedding_lookup函数的用法
关于np.random.RandomState.np.random.rand.np.random.random.np.random_sample参考https://blog.csdn.net/lanc ...
- python3中替换python2中cmp函数
python 3.4.3 的版本中已经没有cmp函数,被operator模块代替,在交互模式下使用时,需要导入模块. 在没有导入模块情况下,会出现 提示找不到cmp函数了,那么在python3中该如何 ...
- react-native 0.57 run-ios 失败解决办法
React Native 日常报错 'config.h' file not found 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/qq_ ...
- unity3d-碰撞检测
碰撞检测 游戏中很多时候都要判断碰撞检测,比如子弹打中敌机.当碰撞后.就要发生爆炸. 或者敌机减血, 我们先看一张图片,看皮球从天空下落.与地面碰撞的过程 碰撞检测条件 游戏中两个对象发生碰撞是需要条 ...
- jQuery 批量操作checkbox
困扰很久的问题: 如果只是 $('input[type=checkbox]').attr('checked',true);//全选 $('input[type=checkbox]').attr('ch ...
- Q-learning简明实例
本文是对 http://mnemstudio.org/path-finding-q-learning-tutorial.htm 的翻译,共分两部分,第一部分为中文翻译,第二部分为英文原文.翻译时为方便 ...