资讯专栏INFORMATION COLUMN

复习Javascript专题(二):闭包,内存,以及垃圾回收机制

hankkin / 1895人阅读

摘要:一个闭包就是当一个函数返回时,一个没有释放资源的栈区所以参数和变量不会被垃圾回收机制回收。使用不当会很容易造成内存泄露。最后,垃圾回收器完成内存清除工作,销毁那些带标记的值并回收它们所占用的内存空间。

1.什么是闭包?闭包有啥特性以及存在什么问题?
概念:闭包是指有权访问另一个函数作用域中的变量的函数。下面的outer就形成了一个闭包:
function outer(){
    const name="nagi";
    return function inner(){
        console.log(name);
    }
 }
let p=outer();
}
let p=outer();

一般来讲,当函数执行完毕后,局部活动对象就会被销毁,内存中仅保存全局执行环境中的变量对象,但闭包有所不同。
当outer()执行完后,因为inner函数的作用域链在引用outer的活动对象,所以它并不会被销毁,而是仍然留在内存中,
除非inner函数也销毁它的活动对象才会被销毁。比如使p=null;

特性: 由上面的代码可以得出以下几个特性:

a. 函数嵌套函数,作为一个函数变量的一个引用,当函数返回时,其处于激活状态。
b. 函数内部可以引用外部的参数和变量。
c. 一个闭包就是当一个函数返回时,一个没有释放资源的栈区,所以参数和变量不会被垃圾回收机制回收。

优点:

 a. 减少全局变量的污染
 b. 可以有私有变量的存在
function counter(){
    let n=0;
    function add(){
        n++;
       console.log(n);
    }
    return {n:n, add:add}
}
const c1=counter();
const c2=counter(); // 它和c1分别存入了不同的堆内存中
c1.add(); // 1
c1.add(); // 2
c1.n;     // 0 // 此处的n是基本类型,除非重新赋值,否则不会变!
c2.add(); // 1 c1和c2互不干涉,都有自己的新的作用域链和新的私有变量
注意!!父函数每次调用会产生新的闭包

缺点(问题)

a.常驻内存,增加内存使用量。
b. 使用不当会很容易造成内存泄露。
另:闭包的多种写法可以参照这里:JavaScript闭包(closure)
2.js中的垃圾回收机制
 原理:js中有自动回收管理内存机制,它的原理是会定期(周期性地)找出那些不再继续使用的变量,然后释放其占用的内存。

内存管理:

1. 分配内存(不管是基本类型还是引用类型)
2. 使用内存(对变量,函数等读取或写操作)
3. 释放内存(使用垃圾回收机制回收内存)
回收方式 1.引用计数
**含义:**跟踪记录每个值被引用的次数。
**工作机制:**
    当声明一个变量并将一个引用类型值赋给它时,则这个值的引用次数就是1;
    如果同一个值又被赋给另一个变量,则该值的引用次数加1;
    相反,如果包含对这个值引用的变量又被赋了其他值,则这个值的引用次数减1;
    当这个值的引用次数为0时,则说明没有办法再访问这个值了;
    这样,当垃圾收集器下次再运行时,便会释放这种引用次数为0的值所占的内存。

问题:

这种方式有一个严重的问题,即“循环引用”。
意思是对象A中包含一个指向对象B的指针,而对象B也包含一个指向对象A的指针,
这样当函数执行完毕后,因为其引用也就永远不会为0,所以对象A和B将继续存在,
如果对象所在函数被重复调用,就会导致大量内存得不到回收。
 function problem(){
     let objA=new Object();
     let objB=new Object();

     objA.someOtherObj=objB;
     objB.antherObj=objA;
 }
2.标记清除(常用方式)
原理:垃圾回收器会在运行时给存储在内存中的所有变量加一个标记。
(当变量进入环境时,就交这个变量标记为“进入环境”。而当变量离开环境时,则将其标记为“离开环境”。)

然后,它会去掉环境中的变量以及被环境中的变量引用的变量的标记(闭包)。

而在这些完成之后再被加上标记的变量将被视为准备删除的变量,原因是环境中的变量已经无法访问到这些变量了。

最后,垃圾回收器完成内存清除工作,销毁那些带标记的值并回收它们所占用的内存空间。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/108822.html

相关文章

  • JS专题垃圾回收

    摘要:如果没有引用指向该对象零引用,对象将被垃圾回收机制回收。经过增量标记改进后,垃圾回收的最大停顿时间可以减少到原来的左右。解除引用的真正作用是让值脱离执行环境,以便垃圾收集器下次运行时将其回收。 前言 在讲 JS 的垃圾回收(Garbage Collection)之前,我们回顾上一篇《JS专题之memoization》,memoization 的原理是以参数作为 key,函数结果作为 v...

    liujs 评论0 收藏0
  • 【重温基础】19.闭包

    摘要:系列目录复习资料资料整理个人整理重温基础篇重温基础对象介绍重温基础对象介绍重温基础介绍重温基础相等性判断本章节复习的是中的关于闭包,这个小哥哥呀,看看。这里随着闭包函数的结束,执行环境销毁,变量回收。 本文是 重温基础 系列文章的第十九篇。今日感受:将混乱的事情找出之间的联系,也是种能力。 系列目录: 【复习资料】ES6/ES7/ES8/ES9资料整理(个人整理) 【重温基础】...

    nanfeiyan 评论0 收藏0
  • 【重温基础】22.内存管理

    摘要:内存泄露内存泄露概念在计算机科学中,内存泄漏指由于疏忽或错误造成程序未能释放已经不再使用的内存。判断内存泄漏,以字段为准。 本文是 重温基础 系列文章的第二十二篇。 今日感受:优化学习方法。 系列目录: 【复习资料】ES6/ES7/ES8/ES9资料整理(个人整理) 【重温基础】1-14篇 【重温基础】15.JS对象介绍 【重温基础】16.JSON对象介绍 【重温基础】1...

    Pandaaa 评论0 收藏0
  • 56 道高频 JavaScript 与 ES6+ 的面试题及答案

    摘要:线程的划分尺度小于进程,使得多线程程序的并发性高。线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入口顺序执行序列和程序的出口。从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。 showImg(https://segmentfault.com/img/bVbv2GE?w=900&h=400); 前言 本文讲解 56 道 JavaScript...

    zengdongbao 评论0 收藏0
  • 温故js系列(14)-闭包&垃圾回收&内存泄露&闭包应用&作用域链&

    摘要:该对象包含了函数的所有局部变量命名参数参数集合以及,然后此对象会被推入作用域链的前端。如果整个作用域链上都无法找到,则返回。此时的作用域链包含了两个对象的活动对象和对象。 前端学习:教程&开发模块化/规范化/工程化/优化&工具/调试&值得关注的博客/Git&面试-前端资源汇总 欢迎提issues斧正:闭包 JavaScript-闭包 闭包(closure)是一个让人又爱又恨的somet...

    Amio 评论0 收藏0

发表评论

0条评论

hankkin

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<