本文介绍JS内存中的堆栈:
- 一、堆栈的基本概念
- 二、堆栈与JavaScript中的基本类型和引用类型
- 参考资料
一、堆栈的基本概念
堆(heap)和栈(stack)是两种数据结构,先进后出,只能在一端对数据进行插入和删除。
栈(stack)的寻址速度要快于堆(heap)。
内存空间中的堆栈:
结构 | 存放方式及大小 | 分配释放者 | 存放数据 | |
---|---|---|---|---|
堆(heap) | 没有结构 | 任意存放,大小未知 | 程序员/由OS回收 | 运行时数据区、对象、自定义类型等 |
栈(stack) | 有结构 | 按次序存放,每个区块大小确定 | 操作系统 | 函数的参数值、局部变量的值 等 |
数据存放的规则:
- 栈(stack):局部的、占用空间确定的数据
- 每个函数/方法都会建立自己的内存栈,存储函数参数和局部变量
- 堆(heap):其他
- 所有的对象
垃圾回收机制:
- 随着函数/方法的执行结束,这个函数/方法的内存栈也将自然销毁
- 堆内存中的对象不会随方法的结束而销毁,即使方法结束后,这个对象还可能被另一个引用变量所引用(方法的参数传递时很常见),只有当一个对象没有任何引用变量引用它时,系统的垃圾回收机制才会在核实的时候回收它。
因此,一般来说,内存泄漏都发生在堆(heap),即某些内存空间不再被使用了,却因为种种原因,没有被系统回收。
举例说明:
|
|
- 变量i和y:栈(stack)
- 局部变量:只用在Method1区块之内,不会用于区块之外
- 占用的内存空间确定:整数
- 变量cls1:栈(stack)
- 局部变量
- 占用的内存空间确定:指针,指向一个对象的实例
- 变量cls1的对象实例:堆(heap)
- 局部变量
- 无法确知所占用的内存空间大小
Method1方法运行结束:
- 整个stack被清空,i、y和cls1这三个变量消失,因为它们是局部变量,区块一旦运行结束,就没必要再存在了
- heap之中的那个对象实例继续存在,直到系统的垃圾清理机制(garbage collector)将这块内存回收
以上是堆栈的基本概念,下面重点剖析JavaScript中的堆栈。
二、堆栈与JavaScript中的基本类型和引用类型
基本类型和引用类型
JavaScript的数据类型分为两大类:
- 基本类型:Undefined、Null、Boolean、Number 和 String
- 引用类型:Object、Array、Function等,变量实际保存的是一个指针,指向另一个位置
内存分配 | 数据大小 | 访问方式 | 本质 | |
---|---|---|---|---|
基本类型 | 栈(stack) | 确定 | 按值访问 | 数据段 |
引用类型 | 堆(heap) | 不确定 | 按引用访问 | 对象 |
- 复制表示对象的某个变量:操作的是对象的引用,复制指针
- 为对象添加属性:操作的是实际的对象,修改对象
举例说明:
|
|
b和obj1变量操作的是同一个对象,c和obj1完全独立的
- 改变b的数据:obj1.name的数据也在改变
- 改变c的数据:obj1.age的值没有变化