JS进阶系列以内存空间

也许不少人像我同样,以为JS有垃圾回收机制,内存就能够无论了,以致于在全局做用域下定义了不少变量,自觉得JS会自动回收,直到最近,看了阮一峰老师,关于javascript内存泄漏的文章时,才发现本身写的代码,存在很严重的内存泄漏问题,再者,由于忽略对内存的学习,致使后面不少进阶概念很模糊,好比深复制与浅复制的区别,好比闭包、做用域链等等。javascript

堆与栈

与C/C++不一样,JavaScript语言没有严格意义上,区分堆与栈,因此咱们能够理解为,JavaScript全部的数据都是存放在堆内存中。
不过,在某些场景下,咱们仍然须要借助堆栈数据结构来处理,因此有必要理解一下这两个数据结构的区别。java

栈:也叫作堆栈程序员

栈数据结构的一个特色就是后进先出,比如羽毛球盒子,在一头放羽毛球,在另一头取羽毛球。
堆数据结构,比如书架上的书,虽然已经按顺序放好了,可是咱们只要知道书的名字,就能够对应的取下来,相似于JSON对象中的key-value数据结构

变量对象与基本数据类型

JavaScript中的数据类型大体分为,基本数据类型引用数据类型,上文提到,JavaScript中全部的数据都是存放在堆内存中,可是,这里提到的变量对象(在执行上下文建立阶段生成),因为它有特殊的职能,因此在理解上就把它与堆内存单独分开了,以下图所示:闭包

image.png
通常变量对象里面存放的是基本数据类型,包括Undefined、Null、Boolean、Number、String,它们到是按值访问的。函数

demo01
var a  = 20;
var b  = a;
b = 30;
console.log(a);//20

上面这段代码指的是,在变量对象中执行数据复制的时候,其实系统会自动为新的变量分配一个新的值,因此a与b其实已是彻底独立的两个变量,只是值同样而已。学习

image.png

堆内存与引用数据类型

javascript中的引用数据类型是存放在堆内存中的,可是不一样于变量对象,javascript是不容许直接访问堆内存中的数据,因此若是咱们要访问引用数据类型的时候,采用的是按引用访问,其实就是在变量对象中存放了一个指向对象的句柄,能够理解为一个地址,要访问堆内存中的对象,就要经过这个引用句柄来访问,例如上图中的d变量,就是一个指向对象的地址。人工智能

demo02
var m = { a:10,b:20};
var n = m;
n.a = 15;
console.log(m.a);//15

上面这段代码指的是执行引用类型数据的复制时,在变量对象中会分配一个新的值,来存放新的变量,可是这两个变量的地址是同样的,至关于指向的对象是同样的,因此各自改变对象里面的属性值,会互相影响,以下图code

image.png

内存泄漏

上面讲解了JavaScript中的内存空间,接下来就要讲解,我写这篇文章的初衷,就是我代码中严重的内存泄漏对象

内存泄漏:就是再也不用到的内存,可是没有及时释放,就叫作内存泄漏

有些语言必须手动释放内存,程序员负责内存的管理,例如C语言

char *buffer;
buffer = (char*) malloc(42);
//do something with buffer
free(buffer);

这里malloc就是负责分配内存,free是负责释放内存。

那么JavaScript中的垃圾回收机制又是怎么一回事呢?

垃圾回收机制

之前我一直天真的觉得,垃圾回收机制就像人工智能同样,会自动帮你识别出不用的内存,而后释放掉,然而真相只有一个
垃圾回收机制的原理就是,使用引用计数法,就是语言引擎有一张“引用表”,保存了内存里面全部的资源的引用次数,就像下面这样

image.png

可是若是一个值再也不须要了,引用数却不为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垃圾回收机制很快作出判断而且回收,可是对于全局变量,很难判断何时不用,因此,经验之谈就是,尽可能少使用全局变量。 咱们在使用闭包的时候,就会形成严重的内存泄漏,由于闭包的缘由,局部变量会一直保存在内存中,因此在使用闭包的时候,要多加当心。

相关文章
相关标签/搜索