js的内存和垃圾回收机制

JavaScript027

js的内存和垃圾回收机制,第1张

在Node中如果通过JavaScript使用内存操作时会发现实际只能使用部分内存(64位系统下约为1.4G,32位系统下约为0.7G),这种限制对于其他的服务端开发语言来说基本上都是不存在的。

而问题的原因在于Node是基于V8构建,所以在Node中使用对象都是通过V8自己的方式进行分配和管理。

而其内存管理机制在浏览器的场景下问题不大,但是对于Node,却使得Node有了这般限制。

老生代中用标记 - 清除(Mark-Sweep)的算法来处理。

首先是标记过程阶段,标记阶段就是从一组根元素开始,递归遍历这组根元素(遍历调用栈),在这个遍历过程中,能到达的元素称为活动对象,没有到达的元素就可以判断为垃圾数据.然后在遍历过程中标记,标记完成后就进行清除过程。它和副垃圾回收器的垃圾清除过程完全不同,这个的清除过程是删除标记数据。

清除算法后,会产生大量不连续的内存碎片。而碎片过多会导致大对象无法分配到足够的连续内存,于是又产生了标记 - 整理(Mark-Compact)算法,这个标记过程仍然与标记 - 清除算法里的是一样的,但后续步骤不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存,从而让存活对象占用连续的内存块。

所谓内存管理,是 js 从创建变量到垃圾回收的一个过程。

分三种:

栈:存放变量,包括基础数据类型的变量及对象的指针

堆:存放引用数据类型的值

池:一般也归类为栈,保存常量

找出那些不再继续使用的变量,然后释放其占用的内存。

不再用到的内存,没有及时释放,就叫做内存泄漏(memory leak)

当内存占用越来越高,轻则影响系统性能,重则导致进程崩溃。Chrome限制了浏览器所能使用的内存极限,64位为1.4GB,32位为1.0GB。

1.意外的全局变量

.未声明变量

.使用this创建的变量(this指向window)

解决办法:

.避免创建全局变量

.使用严格模式,在js文件头部或者函数的顶部加上use strict

2.闭包引起的内存泄露

原因:闭包可以读取函数内部的变量,然后让这些变量是始终保存在内存中。如果在使用结束后没有将局部变量清除,就可能导致内存泄露。

解决:将事件处理函数定义在外部,解除闭包,或者在定义事件处理函数的外部函数中。

3.没有清除的DOM元素引用

原因:虽然别的地方删除了,但是对象中还存在对DOM的引用。

解决办法:手动删除,赋值为null

4.被遗忘的定时器或者回调

解决办法:手动删除定时器和DOM,removeEventListener移除事件监听