内存释放和作用域销毁

来源:互联网 发布:淘宝客cms源码 编辑:程序博客网 时间:2024/06/11 17:21

    对象数据类型和函数数据类型在定义的时候首先会开辟一个堆内存,堆内存有一个引用地址,如果外面有变量已经知道了该引用地址,则会说该内存已经被占用了,那么这个内存就不能够被销毁了。

    那为了保证浏览器的性能,浏览器有时如何释放内存的?

1、对于堆内存的释放,是通过null操作来销毁内存的,只要把所有引用了这个堆内存的变量值赋值为null即可,使得当前的堆内存没有任何东西占用了,那浏览器会在空闲的时候将该堆内存销毁。

2、对于栈内存,主要是指全局作用域和私有作用域。

(私有作用域只有当函数被执行的时候会产生,对于for语句、if语句和switch语句等都不会产生内存的)

  2.1 全局作用域是什么时候被浏览器销毁的?

全局作用域只有当浏览器页面关闭的时候才会关闭。

  2.2 私有作用域是在什么时候被浏览器销毁的?

一般情况下,函数执行会形成一个新的私有作用域,当私有作用域中的代码全部执行完毕后,我们的当前私有作用域会自动进行释放和销毁,当该函数再次被执行时,又会重复创建一个新的私有作用域,然后执行完毕后有销毁,如此重复。

 3、但是也有特殊情况使得私有作用域成为不被销毁或者暂时不销毁的私有作用域,当私有作用域中的部分内容被作用域以外的东西占用了,那么当前的私有作用域就不能销毁。

       如:

    

在图中的内存A就不能被销毁,因为f已经占用了A中部分,也就是说A中的堆内存被A以外的占用了,那xxxfff111堆内存就不能释放,对应的A这个私有作用域也不能被销毁了,里面的私有变量num也不会被销毁。

主要有以下几种情况会发生内存不能被销毁:

 a、函数执行后返回一个引用数据类型值,并且在函数的外面被一个其他东西给接收了,这种情况下形成的私有作用域都不会被销毁。

例子:

function fn() {    var num = 100 ;    return function () {            }}var f = fn(); // ===>fn执行时形成的私有作用域不能被销毁
  b、在私有作用域中给DOM事件绑定方法,一般情况下的这个私有作用域也不会被销毁。
例子:
var obj = document.getElementsByClassName("d");~function () {    obj.onclick = function () {    }}(); //===>这个自执行函数的私有作用域也不能被销毁。
图分析如下:
c、以下情况属于不立即销毁内存情况,因为fn返回的函数没有被其他东西占用,但是还是需要执行一次,所以会暂时不销毁,当返回
的值执行完成后,浏览器会在空闲的时候销毁。
function fn() {    var num = 100 ;    return function () {    }}
fn()();
4、相关练习题:
题一:
function fn() {    var i = 10;    return function (n) {        console.log(n+ (++i));    }}var f = fn();f(10);//21f(20);//32fn()(10);//21fn()(20);//31
输出结果:

结果分析:
题二:
function fn(i) {    return function (n) {        console.log(n+ (i++));    }}var f = fn(13);f(12);//25f(14);//28fn(15)(12);//27fn(16)(23);//39
结果:


原创粉丝点击