

注意:永久代(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限制)。
对于变量,
局部变量存在 栈中,线程私有(包括基本类型和引用类型);
成员变量是对象的一部分,存在堆中;
静态变量存在 方法区中,线程共享(存储类的元数据、静态变量、常量)