Skip to content

内存

通过理解栈内存和堆内存的工作原理,你可以更好地优化代码性能并避免常见的内存管理问题

栈内存和堆内存

在 JavaScript 中,理解栈内存(stack memory)和堆内存(heap memory)对于掌握内存管理机制非常重要。以下是它们的区别和工作原理:

1. 栈内存(Stack Memory)

  • 存储内容:主要用于存储原始类型(primitive types)数据,如 nullundefinedbooleannumberstringsymbolbigint
  • 分配方式:当一个变量被声明时,其值直接存储在栈中。
  • 访问速度:栈内存的访问速度非常快,因为它的结构是线性的,类似于栈的数据结构(后进先出,LIFO)。
  • 生命周期:栈中的变量在其作用域结束时自动释放。例如,函数执行完毕后,局部变量会被从栈中移除。
javascript
let a = 10; // 原始类型,存储在栈中

2. 堆内存(Heap Memory)

  • 存储内容:主要用于存储引用类型(reference types)数据,如 object(包括数组、函数、类实例等)。堆内存用于存储较大的或复杂的数据结构。
  • 分配方式:当一个对象被创建时,它会被分配到堆内存中,而栈中只存储指向该对象的引用(指针)。
  • 访问速度:堆内存的访问速度相对较慢,因为它没有固定的顺序,需要通过引用查找。
  • 生命周期:堆中的对象不会自动释放,通常由垃圾回收机制(Garbage Collection, GC)来管理。当对象不再被引用时,GC 会回收这些对象占用的内存。
javascript
let obj = { name: "Alice" }; // 对象存储在堆中,obj 是指向该对象的引用

3. 两种类型的差异性本质

  • 内存分配

    • 栈内存:简单且快速,适合存储小量且生命周期短的数据。
    • 堆内存:灵活但较慢,适合存储大量且生命周期长的数据。
  • 数据存储

    • 栈内存:直接存储原始类型数据。
    • 堆内存:存储引用类型数据,并在栈中保存指向堆中对象的引用。
  • 内存管理

    • 栈内存:自动管理,随作用域结束自动释放。
    • 堆内存:依赖垃圾回收机制,手动或自动释放未引用的对象。

示例代码

javascript
// 栈内存示例
let num = 42; // 原始类型,存储在栈中

// 堆内存示例
let person = {
  name: "Bob",
  age: 30
}; // 对象存储在堆中,person 是指向该对象的引用

function createObject() {
  let localObj = { key: "value" }; // 对象存储在堆中,localObj 是指向该对象的引用
  return localObj;
}

let newObj = createObject(); // newObj 持有对堆中对象的引用

Released under the MIT License.