JVM内存结构中堆与栈的划分核心依据是线程可见性与数据生命周期:堆为线程共享区域,存储所有对象实例并由GC管理;栈为线程私有,仅存方法调用的栈帧(含局部变量、操作数栈等),生命周期与线程一致。

堆(Heap)——所有对象的统一仓库
堆是JVM管理的最大一块内存区域,线程共享,所有线程都能读写其中的对象实例。
- 所有通过
new创建的对象、数组、字符串常量池(JDK7+起移入堆)、静态变量(JDK7起也存于堆)都分配在这里 - 按对象存活时间分代管理:新生代(Eden + 两个Survivor区)用于短期对象;老年代存放长期存活对象
- 由垃圾收集器(GC)自动管理,会触发
OutOfMemoryError: Java heap space,常见于内存泄漏或大对象堆积 - 大小可通过
-Xms(初始)和-Xmx(最大)参数控制
栈(Java虚拟机栈)——每个线程的私有工作台
栈是线程私有的,每个线程启动时就分配独立一份,生命周期与线程一致,线程结束即销毁。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 不存对象本身,只存方法调用过程中的临时信息:局部变量(基本类型值、对象引用地址)、操作数栈(字节码运算中转站)、动态链接(指向方法区符号引用)、方法返回地址
- 以“栈帧”为单位运作:每调用一个方法,就压入一个栈帧;方法返回,栈帧自动弹出(FILO)
- 栈深度超限(如无限递归)抛出
StackOverflowError;栈空间无法扩展时抛出OutOfMemoryError(较少见) - 大小由
-Xss参数设定(如-Xss256k),设得过大可能减少可创建线程数
别把“栈”和“本地方法栈”混为一谈
Java虚拟机栈专为Java方法服务;本地方法栈则为 native 方法(如用C/C++写的JNI代码)提供支持,两者逻辑分离,但结构相似。它们都是线程私有、不参与GC。
堆与栈的关系很直接:栈里存的是“地址”,堆里存的是“实体”
比如执行 String s = new String("hello");:
– 变量 s(引用)存在当前线程的栈帧局部变量表中;
– 字符串对象 "hello" 实际存储在堆中;
– 栈中的 s 只保存指向堆中该对象的内存地址。

















