Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 

内存空间

  • 基础数据类型与变量对象
  • 引用数据类型与堆内存空间
  • 内存空间管理

基础数据类型与变量对象

最新的 ECMAScript标准号定义了7种数据类型,其中包括六种基础数据类型与一种引用数据类型(Object)。

类型
Boolean 只有两个值: true与false
Null 只有一个值: null
Undefined 只有一个值: undefined
Number 所有的数字
String 所有的字符串
Symbol 符号类型 var sym = Symbol('testsymbol')

由于目前常用的浏览器版本还不支持 Symbol,而且通过 babel 编译之后的代码量过大,因此在实践中建议暂时不要使用 Symbol。

思考一个问题,当运行函数 fn 时,它其中的变量 a1、a2、a3 都保存在什么地方?

function fn() {
  var a1 = 10;
  var a2 = 'hello';
  var a3 = null;
}

函数运行时,会创建一个执行环境(执行上下文 - Execution Context)。在执行上下文中,会创建一个叫作变量对象(VO)的特殊对象,基础数据类型往往都保存在变量对象中。

引用数据类型与堆内存空间

引用数据类型(Object)的值是保存在堆内存空间中的对象。在JavaScript中,不允许直接访问堆内存空间中的数据,因此不能直接操作对象的堆内存空间。在操作对象时,实际上是在操作对象的引用而不是实际的对象。因此,引用数据类型都是按引用访问的。这里的引用,可以理解为保存在变量对象中的一个地址,该地址与堆内存中的对象相关联。

用一段代码解释:

function foo() {
  var a1 = 10;
  var a2 = 'hello';
  var a3 = null;
  var b = {
    m: 20
  }
  var c = [1, 2, 3];
}

内存空间管理

var a = 20;
alert(a + 100);
a = null;

上面的三条语句,分别对应如下三个过程。

  • 分配内存;
  • 使用分配到的内存;
  • 不需要时释放内存(涉及 JavaScript 垃圾回收机制的实现原理);

标记一清除算法

JavaScript 的垃圾回收实现主要依靠“引用”的概念。当一块内存空间中的数据能够被访问时,垃圾回收器就认为“该数据能够被获得”。不能够被获得的数据,就会被打上标记,并回收内存空间。这个算法会设置一个全局对象,并定期地从全局对象开始查找,垃圾回收器会找到所有可以获得与不能够被获得的数据。

上面这个例子中,当我们将 a 设置为 null 时,那么刚开始分配的 20,就无法被访问到了,而是很快会被自动回收。

在局部作用域中,当函数执行完毕后,局部变量也就没有存在的必要了,因此垃圾收集器很容易做出判断并回收。但是在全局中,变量什么时候需妥自动释放内存空间则很难判断,因此我们在开发时,应尽量避免使用全局变量。如果使用了全局变量,则建议不再使用它时,通过 a = null 这样的方式释放引用,以确保能够及时回收内存空间。