JavaScript 中的堆、栈和方法区

46 阅读1分钟

在 JavaScript 中,内存管理主要涉及堆(Heap)和栈(Stack)的概念,但没有像 Java 那样明确的方法区(Method Area)概念。

栈(Stack)

  • 用途:存储原始数据类型和函数调用信息
  • 特点
    • 自动分配固定大小的内存空间
    • 按值访问
    • 后进先出(LIFO)结构
    • 内存分配和释放由系统自动管理

栈中存储的内容包括:

  • 原始数据类型(Number, String, Boolean, Null, Undefined, Symbol, BigInt)的值
  • 函数的调用栈(调用帧)
  • 对象的引用(指针)

堆(Heap)

  • 用途:存储引用类型数据(对象、数组、函数等)
  • 特点
    • 动态分配内存空间
    • 按引用访问
    • 内存分配和释放由垃圾回收机制管理

堆中存储的内容包括:

  • 对象(Object)
  • 数组(Array)
  • 函数(Function)
  • 闭包中的变量

方法区

在 JavaScript 中:

  • 没有明确的方法区概念,这与 Java 不同
  • 函数作为一等公民,其代码通常存储在堆中
  • 函数的原型(prototype)也存储在堆中
  • ES6 的类(Class)本质上也是函数,同样存储在堆中

示例说明

// 原始类型 - 存储在栈中
let num = 10;      // 栈
let str = "hello"; // 栈

// 引用类型 - 对象本身在堆中,引用(指针)在栈中
let obj = {        // 对象在堆,obj变量在栈存储引用
  name: "John"
};

function foo() {   // 函数在堆,foo变量在栈存储引用
  console.log("foo");
}

JavaScript 引擎(如 V8)的具体实现可能有更复杂的内存结构,但作为开发者,我们主要需要理解堆栈的基本概念及其对变量存储和垃圾回收的影响。