垃圾收集,内存问题
垃圾收集机制:手动收集,和自动收集
释放无用的数据,回收内存。
JS可以自动收集,手动收集即把变量设置为Null。
收集原理:找出没用数据,打上标记,释放内存,在一定时间周期内释放内存。
-------
标识无用数据的策略:
1,标记清除
2,计数引用:跟踪记录某个值被引用的次数,当引用次数为0时,说明没有变量引用该值,就可以回收了。
{
var xm={age:18; sex:"male";} //引用该值1次
var xh=xm;//引用该值2次
xh={}; //引用{age:18; sex:"male";} 该值(2-1)=1次
xm={};//引用{age:18; sex:"male";} 该值(1-1)=0次
}
网景Netscape,就是因为循环引用计数才关门大吉。
function fn(argument){
var xm={};//两个对象不同引用,值也不同。该值被引用1次。两个局域变量在执行环境中不会被标记清除
var xh={};//两个对象不同引用,值也不同。该值被引用1次。两个局域变量在执行环境中不会被标记清除
}
fn();//函数执行完毕,局部变量要标记清除,释放内存,这时就会被赋值为:xm=null; xh=null;
-----------循环引用有致命的缺陷-----------
function fn(argument){
var xm={};//引用该值1次。
var xh={};//引用该值1次。
xm.wife=xh;//引用该值2次。
xh.husband=xm;//引用该值2次。
}
fn();//函数执行完毕,局部变量要标记清除,回收内存。
xm=null;
xh=null;
//xm=null; 这里是垃圾回收机制时,系统自动赋值减少一次引用,所以对{}的值引用减少一次 (2-1)=1次,而并非0次。所以该值内存没有清除,如果执行几百上千次,那就会造成内存溢出,系统奔溃。如果要解决该问题,那么我就要手动在函数执行完毕后,把所有局部变量赋值为null。如下最后两行代码。
//xh=null; 这里是垃圾回收机制时,系统自动赋值减少一次引用,所以对{}的值引用减少一次 (2-1)=1次,而并非0次。所以该值内存没有清除,如果执行几百上千次,那就会造成内存溢出,系统奔溃。这就是网景Netspace的致命问题。所以现在大多数浏览器都使用标记清除。如果要解决该问题,那么我就要手动在函数执行完毕后,把所有局部变量赋值为null。如下最后两行代码。
xm.wife=null;
xh.husband=null;
---------------------
内存问题
1,离开作用域的值将被标记可回收,将在垃圾收集期间被删除。
离开作用域的值相当于我们给其赋值为:null。
var a=null;
2,标记清除是目前主流的垃圾回收算法。
即:变量离开作用域将被标记可回收,在垃圾收集期间被删除。
3,标记清除就是给不用的变量添加标记,然后回收其内存。
4,引用计数算法因为循环引用的问题而得不到释放。最好的做法就是将其变量设置为null。
5,当变量不用时,可以手动解除它的引用,将其设置为Null。告诉浏览器这个变量内存可以回收了。
A:为了获得更好的性能,我们需要及时解除无用数据的引用;
B:离开作用域的值不会立刻被回收,只是会被打上标记,在垃圾收集期间才会回收;
C:在老版本的IE中访问非原生JS对象(DOM和BOM元素)时,引用计数这种算法可能导致循环引用的问题;
D:优化内存最佳方式,只保留需要的变量,将没用的变量的内存释放掉,适用于全局变量(局部变量在执行完成后,系统会自动释放内存)):
var a=null; 即解除引用