1. 简介
Java的内存,可以分为栈、堆、方法区、本地方法区、程序寄存器等几个核心部分。这一块的内容,以后壹哥会专门编写文章进行介绍,对于初学者来说,这还不适合我们学习。但是我们现在要先对以下三个概念有所了解:
栈:栈中可以存储基本类型的数据和引用类型的地址。特点: 先进后出,一般空间比较小,存取速度较快。
堆:堆中可以存储引用类型的数据。特点: 空间比较大,存储速度相对较慢。
方法区:方法区中可以存储字符串常量池、静态数据、代码和类的元数据。
我们知道,数组属于引用类型,而数组的引用变量(数组名称)只是一个地址引用。这个引用变量可以指向任何有效的内存空间,只有当这个引用指向有效的空间时,才可以通过引用去操作数组中真正的数据元素。所以数组的引用变量(数组名称)是存储在栈空间中,但真正的数组数据是存储在堆空间中。
2. 代码案例
为了让大家更好地理解数组的内存结构,接下来给大家设计一个代码案例,然后给大家分析一下这个数组的内存结构。
public class Demo01 {
public static void main(String[] args) {
//使用静态初始化的方式初始化一个数组a
//a存放在栈中,a的值是数组的地址,数组的真正数据{5,7,20}存放在堆中
int[] a = {5,7,20};
System.out.println("a的长度为:" + a.length);//3
//整型变量,存放在栈中
int num =8;
System.out.println("num:"+num);
//定义一个新的数组b
int[] b=new int[4];
System.out.println("b的长度是:"+b.length);
//将a赋值给b,是b的指向改变了,但b原先对应的数组依然存在
b=a;
System.out.println("b的长度是:"+b.length);
}
}
内存分析
为了让各位更好地理解基本类型的数据和数组的内存结构,壹哥再给大家绘制下面一张图。
根据上面的代码和下面的内存分析图,我们可以得到如下结论:
●变量a存放在栈中,a的值是数组的首地址,数组的真正数据{5,7,20}存放在堆中;
●整型变量num存放在栈中;
●定义新的数组b,数组名称b存放在栈中,b的数据在堆中;
●将a赋值给b,此时b的指向改变了,但b原先对应的数组依然存在,此时b指向原先a对应的数组数据
大家来看看这个问题:Java中数组在堆内存中的结构是怎么样的?Java中数组在堆内存中的结构究竟是怎样的?
在 Java 中,数组是一种数据结构,可以在堆内存中分配空间,存储一组相同类型的数据。数组在堆内存中的结构与其他对象类似,它包含一个对象头和实际的数组元素数据。
对象头通常包含对象的类型信息和一些标记位,例如 GC 相关的标记位。数组元素数据是按照数组类型定义的顺序排列在内存中的,每个元素所占的空间取决于元素类型的大小。
例如,一个 int 类型的数组在内存中的结构可能如下所示:
其中,Object Header 是对象头部分,Length 是数组长度,Element 0、Element 1、Element Length 分别是数组的元素数据。
需要注意的是,在 Java 中,数组是对象的一种,因此数组在堆内存中分配的空间需要通过 new 运算符来申请。数组变量本身则可以在栈内存中分配空间,存储数组对象的引用。