javaScript的内存分配
变量初始化
javaScript在定义变量时,就完成了内存的分配。
|
|
通过函数调用的内存分配
有些函数调用结果是分配对象内存
|
|
值的使用
使用值的过程实际是对分配内存进行读取与写入的操作。
当内存不在需要使用时释放
利用“垃圾回收器”,主要工作是跟踪内存的分配和使用,以便当分配的内存不在使用时,自动释放它。但要知道某块内存是否需要是无法判定的。
垃圾回收机制——GC
原理:垃圾收集器会定期(周期性)找出那些不再继续使用的变量,然后释放它的内存。
不再使用的变量也就是生命周期结束的变量,当然只可能是局部变量,全局变量的生命周期直至浏览器也在页面才会结束。局部变量只在函数的执行过程中存在,而在这个过程中会为局部变量在堆或栈上分配相应的空间,以存储它们的值,在后再函数中使用这些变量,直至函数结束,而闭包中由于内部函数的原因,外部函数并不能算是结束。
|
|
fn1在a赋值操作后被释放,而fn2,它返回的对象被全局变量b所指向,所以该块内存并不会被释放。
怎么区别那些变量无用:
标记清除
当变量进入环境时,如:在函数中声明一个变量,就将这个变量标记为“进入环境”。当变量离开环境时,就将其标记为“离开环境”。
引用计数
最简单的垃圾收集算法。
如果没有引用指向该对象(即0引用),对象将被垃圾回收机制回收。但现在存在一个循环引用:
|
|
手动解除循环引用:
|
|
内存管理
1、解决什么时候触发垃圾回收的问题:
在IE6中:根据内存分配量运行的,当环境中存在256个变量、4096个对象、64k的字符串任意一种情况是就会触发。但现在脚本复杂,一直存在这么多变量的情况很多,所以垃圾回收就会一直工作,那浏览器就没有办法处理其他任务。
在IE7中做出了调整:触发条件是动态的。初始值和IE6相同,如果垃圾回收器回收的内存分配量低于程序占用内存的 15%,说明大部分内存不可被回收,设的垃圾回收触发条件过于敏感,这时候把临界条件翻倍,如果回收的内存高于 85%,说明大部分内存早就该清理了,这时候把触发条件置回。这样就使垃圾回收工作智能了很多。
2、合理的 GC 方案
1)、JavaScript 引擎基础 GC 方案是(simple GC):mark and sweep(标记清除),即:
- 遍历所有可访问的对象。
- 回收已不可访问的对象。
2)、GC 的缺陷
和其他语言一样,JavaScript 的 GC 策略也无法避免一个问题:GC 时,停止响应其他操作,这是为了安全考虑。而 JavaScript 的 GC 在 100ms 甚至以上,对一般的应用还好,但对于 JS 游戏,动画连贯性要求比较高的应用,就麻烦了。这就是新引擎需要优化的点:避免 GC 造成的长时间停止响应。