JS-垃圾回收机制-执行栈执行上下文-闭包

1 JavaScript 中的垃圾回收机制(GC)

1.1 垃圾回收相关概念

① 什么是垃圾

没有被使用(引用)的对象就是垃圾

② 什么是垃圾回收

没有被引用的对象被销毁,内存被释放,就是垃圾回收

C、C++ 等编程语言需要手动垃圾回收。

Java、JavaScript、PHP、Python 等变成语言自动垃圾回收。

③ 变量的生命周期(何时会被回收)

全局变量: 整个脚本执行完毕,全局变量就被销毁。

局部变量: 函数调用完毕,局部变量就被销毁。

④ 垃圾没有及时回收的后果

没有被及时回收的垃圾会常驻内存,造成内存泄漏

⑤ 垃圾回收的常见算法

- 引用计数
- 标记清除

1.2 引用计数

① 原理

- ① 每个对象都有一个引用标记,记录引用次数
- ② 如果对对象进行引用,引用标记+1
- ③ 如果取消了对对象的引用,引用标记-1
- ④ 当对象的引用标记次数为 0,就变为垃圾对象,会立即被清除。
      // obj1对象引用次数+1,此时为1var obj1 = {name:'obj1'}// obj2对象引用次数+1,此时为1var obj2 = {name:'obj2'}// obj1对象引用次数+1,此时为2obj2.info = obj1;// obj2对象引用次数+1,此时为2obj1.info = obj2// 变量obj1不再引用对象obj1, 对象obj1引用次数-1,此时为1obj1 = null;// 变量obj2不再引用对象obj2, 对象obj2引用次数-1,此时为1obj2 = null;

② 优缺点:

- 优点: 垃圾对象比清除地非常及时
- 缺点: 如果两个对象互相引用,会造成两个对象常驻内存,造成内存泄漏

1.3 标记清除

① 原理

浏览器会不停地进行垃圾回收的循环,每次循环经历两个阶段:
- 标记阶段:从根对象开始,一层一层向下找,对所有的能找到的对象进行标记,有标记的对象成为可到达对象,没有标记的对象就是不   可到达对象,也就是垃圾对象。
- 清除阶段线性变量内存中所有的对象,如果对象没有标记就作为垃圾被清除。清除完垃圾之后,去掉所有对象的标记,继续进行下一轮的标记清除。

② 优缺点

- 优点:不会造成内存泄漏
- 缺点:需要进行深度递归遍历,垃圾回收不如引用计数方式更及时。
         // 可通过obj1,找到对象obj1可到达var obj1 = {name:'obj1'}// 可通过obj2,找到对象obj2可到达var obj2 = {name:'obj2'}// obj1仍然可到达obj2.info = obj1;// obj2可到达obj1.info = obj2// 无法通过obj1到达对象obj1obj1 = null;// 无法通过obj2到达对象obj2obj2 = null;

2 执行上下文和执行栈

2.1 执行上下文

① 全局执行上下文

1. 全局代码正式执行之前,创建全局执行上下文对象,赋值给 window。
2. 对全局的数据进行预处理① 所有使用 var 声明的全局变量进行提升,添加为 window 的属性。② 所有使用 function 关键字声明的函数进行提升,添加为 window 的方法。③ 给 this 赋值为 window
3. 开始执行全局代码

② 函数内的执行上下文

1. 当函数被调用的时候,函数体内的代码执行之前,先创建函数的执行上下文对象
2. 对局部的数据进行预处理① 给形参赋值,把形参添加为执行上下文对象的属性。② 给 arguments 赋值,添加为执行上下文对象的属性。③ 对函数内使用 var 声明的变量进行提升,添加为执行上下文对象的属性。④ 对函数内使用 function 关键字声明的函数进行提升,添加为执行上下文对象的方法。⑤ 给 this 赋值为调用该函数的对象(this不是执行上下文对象)
3. 开始执行函数体的代码

注意: 函数每调用一次,就创建一个执行上下文对象!

2.2 执行栈

执行栈也叫调用栈,用于存储代码执行过程中产生的执行上下文对象。

使用经典的数据存储结构,特点是先进后出、后进先出。 数据进入栈成为压栈进栈, 数据移除栈(销毁)称为出栈

1. 代码执行之前,创建一个执行栈对执行上下文对象进行管理。
2. 全局执行上下文对象创建之后,进入执行栈(进栈)
3. 当调用函数的时候,会创建本次函数调用的执行上下文对象,进入执行栈(进栈)
4. 函数调用结束,本次函数调用的执行上下文对象被销毁(出栈)
5. 最后,栈中只剩全局执行上下文对象,待所有代码执行完毕,出栈。

2.3 作用域和执行上下文的关系

区别:
1. 作用域是静态的,变量的作用域只与所在函数声明的位置有关,无在哪里调用无关。
2. 执行上下文对象是动态的,没调用一次函数,就创建一个执行上下文对象。联系:
执行上下文对象也属于所在的所用域
全局执行上下文 -> 全局作用域
函数的执行上下文 -> 函数的局部作用域
 console.log('global begin:'+i);  //undefinedvar i = 1;foo(i);function foo(i) {if (i == 4) {return;}console.log('foo() begin:'+i)foo(i + 1);console.log('foo() end:'+i)}console.log('global end:' + i);/*global begin undefinedfoo() begin 1foo() begin 2foo() begin 3foo() end 3foo() end 2foo() end 1global end 1*/

3. 闭包

3.1 什么是闭包?

1)简单讲,闭包就是指有权访问另一个函数作用域中的数据。
2)MDN 上面这么说:闭包是一种特殊的对象。它由两部分构成:函数,以及创建该函数的环境。环境由闭包创建时在作用域中的任何局部变量组成。

3.2 如何产生闭包

 // 声明函数 A
function A() {// 定义局部变量var a = 100;var b = 200;// 定义函数 Bfunction B() {return a + b;}// 把函数返回return B;
}// 调用函数 A 并获取返回值
var fn = A();// 调用函数 fn
console.log(fn());
1. 有函数A,函数A中有自己作用域的数据, 在函数A里面定义函数B
2. 函数B中使用函数A里面的数据
3. 函数B作为函数A的返回值,或者让函数B被其他方式引用(作为事件的回调函数、赋值给全局变量)

闭包的演示

var liItems = document.querySelectorAll('#newsList li');liItems.forEach(function(liItem,index) {liItem.onclick = function() {console.log('索引为:',index)}})//第二种演示for (var i=0;i<liItems.length;i++) {(function(i) {liItems[i].onclick = function() {console.log('索引为:',i)}})(i)}

3.3 闭包和作用域

1. 函数(函数B)可以反问上层作用域中(函数A)的数据
2. 变量的作用域只与函数声明的位置有关系

3.4 闭包和垃圾回收

1. 闭包导致局部变量除了被自己的执行上下文对象引用,还被函数以外的其他函数所引用
2. 函数调用结束,局部也不会变为垃圾对象
3. 总结: 闭包延长了局部变量的生命周期!

3.5 闭包的缺点

闭包延长了局部变量的生命周期,局部变量常驻内存,有内存泄漏的风险。

JS-垃圾回收机制-执行栈执行上下文-闭包相关推荐

  1. js垃圾回收机制,内存泄露和内存溢出,解决闭包产生的内存泄露详解

    一.内存的周期和回收机制 分配内存----->使用内存----->释放内存 1.JS 环境中分配的内存有如下声明周期: 内存分配:当我们声明变量.函数.对象的时候,系统会自动为他们分配内存 ...

  2. 前端面试常考题:JS垃圾回收机制

    摘要:众所周知,应用程序在运行过程中需要占用一定的内存空间,且在运行过后就必须将不再用到的内存释放掉,否则就会出现下图中内存的占用持续升高的情况,一方面会影响程序的运行速度,另一方面严重的话则会导致整 ...

  3. js垃圾回收机制(Gc)

    js垃圾收机制(Gc) 1.GC(garbage collection):js具有自动垃圾回收机制,即执行环境会负责管理代码执行过程中使用的内存, 2.GC会定期(周期性)找出那些不再继续使用的变量, ...

  4. 从闭包函数的变量自增的角度 - 解析js垃圾回收机制

    GitHub 前言 感觉每一道都可以深入研究下去,单独写一篇文章,包括不限于闭包,原型链,从url输入到页面展示过程,页面优化,react和vue的价值等等. 代码实现 const times = ( ...

  5. js垃圾回收机制和引起内存泄漏的操作

    Js具有自动垃圾回收机制.垃圾收集器会按照固定的时间间隔周期性的执行. JS中最常见的垃圾回收方式是标记清除. 工作原理:是当变量进入环境时,将这个变量标记为"进入环境".当变量离 ...

  6. 面试题——js垃圾回收机制和引起内存泄漏的操作

    JS的垃圾回收机制了解吗? Js具有自动垃圾回收机制.垃圾收集器会按照固定的时间间隔周期性的执行. JS中最常见的垃圾回收方式是标记清除. 工作原理:是当变量进入环境时,将这个变量标记为"进 ...

  7. JS 垃圾回收机制以及垃圾回收策略

    垃圾回收机制 什么是垃圾回收机制: 解释:执行环境负责管理代码执行过程中使用的内存.JS的垃圾回收机制是为了以防内存泄漏,简单来说就是:间歇的不定期的寻找到不再使用的变量,并释放掉它们所指向的内存. ...

  8. js垃圾回收机制详解

    简介 一.前言 二.什么是内存泄漏 1. 引用计数 2. 标记清除 三.总结 一.前言 大家好,我是思航.最近我们游戏在进行内存优化,所以大家网上找了很多教程,来定位和查找内存泄漏问题.今天呢,我打算 ...

  9. JS 垃圾回收机制解析

    概述 JS是一门具有自动垃圾回收机制的语言,开发人员不必关心内存分配和回收问题. JS的垃圾回收机制是为了以防内存泄漏,内存泄漏的含义就是当已经不需要某块内存时这块内存还存在着,垃圾回收机制就是间歇的 ...

最新文章

  1. python csv库,Python 中导入csv数据的三种方法
  2. 【深度学习】遗传算法优化GAN
  3. Ubantu18.04安装Vivado
  4. 利用正则匹配url是否合法对于有的url会浪费过长时间使程序卡死,切记!
  5. Veeam 发布 2022 年数据保护趋势报告,开发者需关注哪些点?
  6. 第一章 进程与线程的基本概念
  7. Java RMI远程方法调用学习总结
  8. log4j日志级别以及配置
  9. 游戏筑基开发之动态数组(C语言)
  10. 如何使用Secure CRT连接到华三模拟器上和华为模拟器上(更新模拟器版本,SecureCRT版本)
  11. 利用端口映射解决:拥有公网IP有限,内网需要访问因特网
  12. sql server系统数据库,temp库的用途
  13. 【android自定义控件】LinearLayout定义ActionBar样式
  14. php特殊字体生成,生成艺术字体图片水印代码_PHP教程
  15. sql 的 desc和asc用法
  16. 基因加性方差、显性方差与上位性方差定义
  17. 为富人服务,挣富人的钱
  18. 三维向量求夹角(0-360)
  19. GPL和LGPL的区别!
  20. 脉冲多普勒雷达设计附matlab代码

热门文章

  1. Eclipse 皮肤
  2. java常见对象_Java各种对象理解
  3. 结构体前面加星号_C语言中带星号的类型指针有哪些特性
  4. 查看本地服务器MYSQL的端口号
  5. 软考信息安全工程师学习笔记汇总
  6. 查看oracle小补丁号,oracle 补丁号查询
  7. Mybatis批量删除
  8. Qt从入门到放弃_0x01:建立项目
  9. 实现用户注册功能---文件保存信息,如果用户名存在就死循环继续
  10. test命令用法。功能:检查文件和比较值