对于二维数组,在本质上是由一堆对象组成的,最外层的二维数组、内层的一维数组和一维数组内的数据或者对象。
1、当对象是一起提供的时,那么对于基本数据类型在内存上的空间是连续的,如果二维数组中的一维数组里面存储的是对象,也算是连续的。
当存储的是基本数据类型时,例如 arr1 数组,需要存储外层的二维数组和内层的一位数组,两者是分开的。
int[][] arr1 = new int[][]{
{1, 2, 3},
{2, 3, 4}
};
a:外层的二维数组需要存储什么数据呢?外侧数组存储模式和内层的一维数组存储模式基本相同
-
第一部分:markword(8字节),用于存储数组的 hashCode,锁信息等等
-
第二部分:class指针(4字节)
-
第三部分:存储数组的大小(4字节),所以说数组的最大个数为 2^32
-
第四部分:数组元素和 + 对齐字节(8 字节的整数倍),这里的数组元素存储的就是每一个一维数组的内存地址引用,全部存储之后若总的字节数不是 8 的整数倍就会在前面使用 0 将数据总量补齐到 8 的整数倍。
b:内层一维数组的存储方式?
在外层二维数组中存储了每一个一维数组的内存地址,那么在内存中就会在每一个一位数组分配的内存地址存储相应的一维数组的数据,存储方式也是分成了 4 个部分。
分别是 markword、class指针、存储数组的大小 和 数组元素和 + 对齐字节。
在一次性内配内存数据时,会将外层数据和内存数据的内存连续分配【只考虑内存充足的情况】,所以说对于基本数据类型在内存上的空间是连续的。
当存储对象时为什么算是连续的呢?
因为在存储对象时,一位数组中的数据存储的是每一个对象的内存地址引用,不是相应的数据,但是真实的数据也会紧挨着进行存储,所以这个说法是也算连续的。
Teacher[][] teachers = new Teacher[][]{
{new Teacher(1, "zs")},
{new Teacher(4, "李四")}
};
2、当二维数组的数据不是一次性提供的时,那就大概率不连续了。
例如:arr1[0] = new int[]{5, 6, 7}; 这样修改 arr1 的数据,那么新分配的内存空间和之前的就不连续了,它不会将现在的数据替换原来的数据。而是后续让 JVM 垃圾回收机制将原始数据的内存自动回收。