垃圾收集
执行环境 会负责管理 代码执行过程中使用的内存
- 内存的分配和无用内存的回收,完全实现了自动管理
- 垃圾收集器:
- 会按照固定的时间间隔(或代码中预定义的收集时间)来周期性地释放无用内存
- 会给无用变量打上标记,以备将来回收
- 标记无用变量的策略会因实现而异
- 通常有两个策略:标记清除(mark-and-sweep)和引用技术(reference counting)
标记无用变量的策略: 标记清除
- 最为常用
- 标记变量是“进入环境”还是“离开环境”
- 不同浏览器的回收时间间隔不同
标记无用变量的策略: 引用技术
引用类型的值:
- 赋给一个变量时,引用次数+1
- 包含这个值的变量被赋了其他值时,引用次数-1
垃圾回收器会释放那些引用次数为0的值所占的内存
但当有循环引用时,这种策略就会遇到麻烦,导致内存泄漏 以下例子中:
- 两个引用类型的值的引用次数都为2
- 但这个方法退出后,它们的引用次数都永远不会为0
//循环引用
function problem ()
{
var objectA = new Object();
var objectB = new Object();
objectA.someOtherObject = objectB;
objectB.anotherObject = objectA;
}
历史:
- Netscape:
- 最早开始使用引用技术策略,但在Navigator 4.0中也放弃了这一策略,转而使用标记清除策略
- IE:
- IE 9之前,有一部分对象不是原生的Javascript对象,例如
BOM和DOM(c++ com实现的,实际上用的是引用计数策略) - 因此,IE 9之前,即便IE的引擎是使用标记清除策略,但只要在IE中涉及COM对象,就会存在循环引用的问题
- IE 9之前,有一部分对象不是原生的Javascript对象,例如
//DOM元素element和原生javascript对象myObject之间的循环引用
var element = document.getElementById("some_element");
var myObject = new Object();
myObject.element = element;
element.someObject = myObject;
解决: 不用的时候,手动断开连接
myObject.element = null;
element.someObject = null;
垃圾收集时间间隔
- 关于垃圾回收收集器多长时间运行一次,这让人想起IE因此而声明狼藉的性能问题
- IE的垃圾收集器是根据内存分配量而运行的,达到以下任何一个临界值,垃圾收集器就会运行
- 256个变量
- 2096个对象字面量和数组元素
- 64KB字符串
- IE 7的Javascript引擎,重写了垃圾收集例程
- 临界值会动态调整
- 在运行包含大量Javascript的页面时,性能得到提升
在有的浏览器中,可以触发垃圾收集,但是不建议这么做
- IE: window.CollectGarbage()
- Opera7, window.opera.collect()
内存管理
系统分配给Web浏览器的可用内存数量,通常要比分配给桌面应用程序的少 目的:
- 放置运行Javascript的网页耗尽全部系统内存,而导致系统崩溃 结果:
- 影响给变量分配内存
- 影响调用栈
- 影响一个线程中能够同时执行的语句数量 因此,需要:
确保占用最少的内存,可以让页面获得更好的性能 优化内存占用的最佳方式:为执行中的代码只保存必要的数据
- 一旦数据不再游泳,最好将其值设为null,来解除引用
- 这适用于:
- 大多数全局变量和全局变量的属性
- 局部变量,会在离开执行环境是,自动被解除引用
function createPerson (name) {
var localPerson = new Object();
localPerson.name = name;
//localPerson自动被解除引用
return localPerson;
}
var globalPerson = createPerson("Nicholas");
globalPerson = null;