java数组变量存栈中仅保存引用,数组对象(含所有元素)均在堆中分配;多维数组是“引用层+数据层”的嵌套结构,体现栈堆分离原则。

Java数组的内存布局,关键在分清“数组变量”和“数组对象”——前者存栈里,后者在堆中。理解这点,就抓住了Java内存模型的核心逻辑。
数组变量(引用)在栈中
当你写 int[] arr = new int[5];,左边的 arr 是一个局部变量,它本身不存数据,只存一个地址(即“引用”)。这个变量被分配在当前方法的栈帧里,生命周期随方法调用结束而自动销毁。
栈中的 arr 就像一张小纸条,上面写着:“去堆里找地址 0x1a2b3c”。它不关心数组内容,只负责指路。
数组对象(实际数据)在堆中
右边的 new int[5] 才是真正在堆上开辟一块连续内存空间:5个 int(共20字节),每个元素初始化为0。这块空间由JVM管理,GC会在它不再被任何栈中引用指向时回收。
注意:即使数组元素是引用类型(如 String[] strs = new String[3];),堆中也只存3个 null 引用值,真正 String 对象(如果后续创建)仍各自独立分配在堆中。
多维数组的结构更清晰体现栈堆分离
int[][] matrix = new int[2][3]; 的内存布局是:
- 栈中:变量 matrix 存的是一个地址,指向堆中“外层数组对象”
- 堆中:先有一块存放2个引用的空间(即2个 int[] 的地址),每个引用又分别指向另一块堆内存(各含3个 int)
所以二维数组不是“一块矩形内存”,而是“一层引用 + 两层实际数据”,天然体现Java一切对象都在堆、一切局部变量(含引用)都在栈的设计原则。
常见误区提醒
很多人误以为“基本类型数组内容在栈”,这是错的。只要用了 new,整个数组对象(包括所有元素)就在堆中。唯一在栈里的,只有那个引用变量本身。
验证方式很简单:在方法内创建数组并返回它,调用方依然能正常使用——说明数据没随方法结束而消失,印证了它在堆中。
不复杂但容易忽略。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











