而问题的原因在于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移除事件监听