局部变量表中数组变量仅占1个slot存储引用,实际元素存于堆;slot可复用以降低栈压力,但编译期已固定总大小,作用域控制比分支位置更影响空间效率。

局部变量表本身不直接存储数组对象,而是存储数组的引用(reference)——即指向堆中数组对象首地址的一个指针或句柄。所谓“数组变量”的内存布局优化,本质是 JVM 对 引用存储 和 Slot 复用 两个层面的处理,而非对数组内容做特殊安排。
数组变量只占一个 Slot(32位引用)
在局部变量表中,声明如 int[] arr = new int[1000]; 这样的语句,局部变量表仅分配 1 个 Slot 来存放 arr 这个引用值。无论数组长度是 1 还是 100 万,只要它是普通对象引用(非 long/double),就只占一个 32 位槽位。
- 该 Slot 存储的是 JVM 能解析的地址信息(可能是堆中对象头起始地址,也可能是方法区中类型元数据的间接索引)
- 数组的实际元素(
int[1000]占 4000 字节)全部分配在堆内存,与局部变量表无关 - 若声明的是
long[]或double[],引用本身仍是 32 位(或 64 位,取决于 JVM 实现),仍只占 1 个 Slot;只有long/double类型的局部变量值才强制占 2 个 Slot
作用域结束即触发 Slot 复用,减少栈帧开销
数组引用变量一旦超出作用域(例如 if 块结束、循环末尾、方法 return 前),其占用的 Slot 就可被后续变量复用。这对频繁创建临时数组的方法特别关键。
- 例如:在一个 for 循环内每次新建
String[] temp = ...,编译后很可能所有temp共享同一个 Slot 索引 - 复用不改变栈帧大小,但能压缩实际活跃变量数,降低栈空间压力
- 注意:复用不等于自动置 null;若未显式赋 null,原引用仍可能阻止 GC 回收堆中数组对象
编译期确定容量,无运行时扩容机制
局部变量表总大小(maximum local variables)在 .class 文件的 Code 属性中固化,由 javac 静态分析得出。包含数组声明在内的所有局部变量、参数数量,都在编译时计入总 Slot 数。
- 哪怕运行时 never 执行到某段含数组声明的分支,该分支所需 Slot 仍被预留(JVM 不做控制流敏感的 Slot 分配)
- 因此,把大数组声明放在深层嵌套或条件分支中,并不能节省栈帧空间;真正省空间的方式是缩小作用域或提前释放引用
- 可通过
javap -v查看方法的max stack和max locals值,验证编译结果











