注意:永久代(1.8 之前)以及元空间(1.8 以及之后)是 HotSpot 虚拟机对虚拟机规范中方法区的两种实现方式。

1. 堆(Heap)
  • 存储内容:所有 对象实例数组。无论是通过 new 创建的对象,还是数组,都存放在堆中。

  • 特点:

    • 线程共享:所有线程都可以访问堆中的对象。

    • 动态分配:对象的创建和销毁由垃圾回收器(GC)自动管理。

    • 内存大小可变:可通过 -Xmx-Xms 参数调整堆的最大和初始大小。

2. 栈(Stack)
  • 存储内容:每个线程的 局部变量方法调用栈帧操作数栈

  • 特点:

    • 线程私有:每个线程有独立的栈空间,不能共享。

    • 后进先出(LIFO):方法调用时入栈,方法返回时出栈。

    • 内存连续:栈帧的分配和释放是快速的(通过指针移动)。

3. 方法区(Method Area)
  • 存储内容:类的 元数据(如类结构、字段、方法字节码)、静态变量常量池即时编译(JIT)后的代码

  • 特点:

    • 线程共享:所有线程都可以访问方法区。

    • 永久代(PermGen) vs 元空间(Metaspace):

      • Java 7 及以前:方法区称为 永久代(PermGen),物理上是堆的一部分,逻辑上是独立区域,有固定大小限制。

      • Java 8 及以后:方法区被 元空间(Metaspace) 取代,使用本地内存(Native Memory),默认无上限(可通过 -XX:MetaspaceSize-XX:MaxMetaspaceSize 限制)。

对于变量,

  • 局部变量存在 栈中,线程私有(包括基本类型和引用类型);

  • 成员变量是对象的一部分,存在堆中;

  • 静态变量存在 方法区中,线程共享(存储类的元数据、静态变量、常量)

我也放荡不羁爱自由!