跳转到主内容
websoft网络软件专家 - 深耕网络技术,打造实用软件!

Java数组底层内存布局解析:堆内存变量连续存储机制教程

数组对象本体在堆上且物理连续,含对象头、length字段和数据区;引用变量在栈中存地址,基本类型数组存值,引用类型数组存地址,传参时修改元素影响原数组,重赋数组引用则不影响。

数组对象本体在堆上,连续分配Java中所有数组都是对象,创建时(如new int[5])会在堆内存中开辟一块连续的、固定大小的空间。这块空间包含三部分:对象头(含GC标记、类元信息)、4字节的length字段、紧接着的原始数据区。比如int[3]实际占用约 12(对象头)+ 4(length)+ 3×4 = 28 字节,且这28字节是物理地址连续的。

引用变量在栈上,只存地址声明语句int[] arr;本身不创建数组,只是在当前方法的栈帧里分配一个4或8字节的引用槽位(取决于JVM指针压缩),初始值为null。执行arr = new int[5];后,该槽位被填入堆中那块连续内存的起始地址。方法结束时,栈帧销毁,这个引用消失;若无其他引用指向该数组,它就进入垃圾回收队列。

基本类型 vs 引用类型数组:存的是什么?

两者都在堆上,但数据区内容不同:int[]、double[] 等:数据区直接存放数值,如new int[]{1,2,3}→ 堆中存的就是 1、2、3 这三个整数String[]、User[] 等:数据区存放的是引用值(即地址),每个元素可能是 null,也可能指向堆中其他位置的 String 或 User 对象这意味着对String[] s = new String[2]; s[0] = "a";,堆中其实有两处独立对象:一个是长度为2的数组对象,另一个是字符串 "a" 实例,s[0] 存的是后者的地址。

Eclipse导入Android或其他的JAVA项目的正确方法 WORD版本文档主要讲述的是Eclipse导入Android或其他的JAVA项目的正确方法;希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看下载立即学习“Java免费学习笔记(深入)

”;

共享与修改:传参和赋值的本质区别向方法传数组,传递的是引用的副本(即地址拷贝),所以:修改arr[i] = x→ 影响原数组(因为操作的是同一块堆内存)

但执行arr = new int[10]→ 只改变形参引用所指的位置,原变量仍指向旧数组同理,int[] a = b;是让 a 和 b 指向同一块堆内存;后续通过 a 或 b 修改元素,对方立刻可见。

相关文章