资讯专栏INFORMATION COLUMN

《javascript高级程序设计》笔记:内存与执行环境

fuyi501 / 1422人阅读

摘要:因此,所有在方法中定义的变量都是放在栈内存中的当我们在程序中创建一个对象时,这个对象将被保存到运行时数据区中,以便反复利用因为对象的创建成本通常较大,这个运行时数据区就是堆内存。

上一篇:《javascript高级程序设计》笔记:继承
近几篇博客都会围绕着图中的知识点展开

由于javascript是一门具有自动垃圾收集机制的编程语言,开发者不必担心内存的分配和回收的问题。因此,内存一词在javascript编程中被开发者提及较少,更有一些非专业计算机相关专业出身的开发人员对javascript中内存的概念全无,但这丝毫不影响内存在编程中的重要程度

1. 堆内存/栈内存

1、存放变量的比较

栈内存用于存放基本类型、引用类型的地址和程序的执行(占用内存已知)
堆内存用于存放引用类型的真实内容,用于存放对象和函数(占用内存未知)

2、存取方式的比较

栈内存:“先进后出,后进先出”——类比兵兵球盒,仅当上面的出栈才能执行下面的

堆内存:“随意存取”——类比书橱,不受入栈出栈的影响,需要某个对象或方法时,使用指针引用即可

3、内存为什么区分堆和栈(重点)

内存占用大小一定程度上决定了程序执行的流畅程度,内存区分堆和栈就是从内存管理机制上使程序运行时占用的内存最小(这与垃圾回收机制有关,后续介绍)

当一个方法执行时,每个方法都会建立自己的内存栈(执行环境),在这个方法内定义的变量将会逐个放入这块栈内存里,随着方法的执行结束,这个方法的内存栈也将自然销毁了。因此,所有在方法中定义的变量都是放在栈内存中的;

当我们在程序中创建一个对象时,这个对象将被保存到运行时数据区中,以便反复利用(因为对象的创建成本通常较大),这个运行时数据区就是堆内存。堆内存中的对象不会随方法的结束而销毁,即使方法结束后,这个对象还可能被另一个引用变量所引用(方法的参数传递时很常见),则这个对象依然不会被销毁,只有当一个对象没有任何引用变量引用它时,系统的垃圾回收机制才会在核实的时候回收它

4、基本类型与引用类型(内存分析)

在博客《javascript高级程序设计》笔记:值类型与引用类型中有详细讲解

5、垃圾回收

javascript 具有自动垃圾收集机制,也就是说,执行环境会负责管理代码执行过程中使用的内存

不再用到的内存,没有及时释放,就叫做内存泄漏(memory leak)

好比一个餐厅,盘子总是有限的,所以服务员会去巡台回收空盘子
(1)自动回收:标记清除会将空盘和装菜的盘作上标识,当服务员巡台时,会收回空盘,释放内存
(2)手动回收:手动倒掉了盘子里面的菜(=null),在下次巡台时那盘子就会被收走了
(3)内存泄露:装着菜的盘子巡台时无法回收,但没有到客人桌上

2. 执行环境

执行环境(execution context)也被称为执行上下文,它是javascript中最为重要的一个概念

执行环境定义了变量或函数有权访问的其他数据,决定了他们各自的行为

每个执行环境都有一个与之关联的变量对象,环境中定义的所有变量和函数都保存在这个对象中(包括arguments/函数/变量)

每次当控制器转到可执行代码(全局或执行函数)的时候,就会进入一个执行上下文。执行环境创建时,变量对象、作用域链和this指向确定(和面章节会介绍)

执行上下文可以理解为当前代码的执行环境,它会形成一个作用域。JavaScript中的运行环境大概包括三种情况:
(1)全局环境:JavaScript代码运行起来会首先进入该环境
(2)函数环境:当函数被调用执行时,会进入当前函数中执行代码
(3)eval

因此在一个JavaScript程序中,必定会产生多个执行上下文。栈底永远都是全局上下文,而栈顶就是当前正在执行的上下文

下面结合代码和图解分析:

var color = "blue";

function changeColor() {
  var anotherColor = "red";

  function swapColors() {
    var tempColor = anotherColor;
    anotherColor = color;
    color = tempColor;
  }

  swapColors();
}

changeColor();

步骤:
(1)全局上下文入栈
(2)碰到changeColor()后,changeColor的执行上下文入栈
(3)碰到swapColors()后,swapColors的执行上下文入栈
(4)swapColors()执行完毕,swapColors的上下文从栈中出栈
(5)changeColor()执行完毕,changeColor的上下文从栈中出栈

图解:

调试图解:
(1)进入全局上下文(可以看到变量提升的效果)

(2)进入changeColor执行环境

(3)进入swapColors执行环境,图中形成了一个闭包closure,里面有变量anotherColor值

(4)swapColors的执行环境出栈,回到changeColor执行环境,闭包消失

(5)changeColor的执行环境出栈,回到全局环境

总结:
(1)全局执行环境在js代码开始执行时就创建了,在浏览器关闭时出栈
(2)每次某个函数被调用,就会有个新的执行上下文为其创建,即使是调用的自身函数,也是如此
(3)函数的执行上下文的个数没有限制
(4)同步执行,只有栈顶的上下文处于执行中,其他上下文需要等待

下一篇:《javascript高级程序设计》笔记:变量对象与预解析
经典推荐:《javascript高级程序设计》笔记:原型图解

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

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

相关文章

  • JavaScript高级程序设计笔记:变量、作用域、内存问题

    摘要:作用域链中的下一个变量对象来自包含外部环境,而再下一个变量对象则来自下一个包含环境。这样,一直延续到全局执行环境全局执行环境的变量对象始终都是作用域链中的最后一个对象标识符解析沿作用域链一级一级搜索标识符。 一、写在前面 最近研究了创建Android虚拟机、vscode结合weex开发Android APP、Vmware装MAC虚拟机的事,看的内容不够多,接下来加油 二、变量、作用域和...

    U2FsdGVkX1x 评论0 收藏0
  • JavaScript高级程序设计笔记:变量、作用域和内存问题(四)

    摘要:局部变量只在函数执行过程中存在。此时,局部变量就没有存在的必要了,因此可以释放他们所占的内存以供他们使用。引用计数的含义是跟踪记录每个值被引用的次数。这一做法适合于大多数全局变量和局部变量的属性。 基本类型和引用类型的值 ECMAScript变量可能包含两种不同数据类型的值:基本类型值和引用类型值。基本类型值指的是简单的数据段,而引用类型的值指那些可能有多个值构成的对象。 动态的属性 ...

    Zack 评论0 收藏0
  • JavaScript高级程序设计》(第3版)读书笔记 第4章 变量、作用域和内存问题

    摘要:具体说就是执行流进入下列任何一个语句时,作用域链就会得到加长语句的块。如果局部环境中存在着同名的标识符,就不会使用位于父环境中的标识符访问局部变量要比访问全局变量更快,因为不用向上搜索作用域链。 基本类型和引用类型的值 ECMAscript变量包含 基本类型值和引用类型值 基本类型值值的是基本数据类型:Undefined, Null, Boolean, Number, String ...

    lidashuang 评论0 收藏0
  • javascript高级程序设计笔记:变量对象预解析

    摘要:检查当前上下文中的参数,建立该对象下的属性与属性值。检查当前上下文的函数声明,也就是使用关键字声明的函数。如果该变量名的属性已经存在,为了防止同名的函数被修改为,则会直接跳过,原属性值不会被修改。 上一篇:《javascript高级程序设计》笔记:内存与执行环境showImg(https://segmentfault.com/img/bVY4xr?w=1146&h=374); 上篇文章...

    tyheist 评论0 收藏0
  • javascript高级程序设计笔记:值类型引用类型

    摘要:因此,出于性能的考虑,在拷贝的方式选择上,应该结合具体的业务环境来进行选择参考专题之深浅拷贝深入剖析的深复制 基本数据类型是按值访问的,因为可以操作保存在变量中的实际的值;引用类型的值是保存在内存中的对象,在操作对象时,实际上是在操作对象的引用而不是实际的对象; 值类型 如果一个变量存储的是值的本身那么就是一个值类型number / string / Boolean / Null / ...

    TerryCai 评论0 收藏0

发表评论

0条评论

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