一维数组内存分析
Java虚拟机的内存划分
区域名称 | 作用 |
---|---|
方法区(Method Area) | 存储类信息、常量、静态变量、即时编译器编译后的代码等数据。 |
堆(Heap) | 存储对象实例及数组,由于 Java 程序中大部分对象都在堆中分配内存,因此堆是 Java 程序中最常用的区域。 |
栈(Stack) | 存储方法的局部变量、方法的参数、方法调用和返回地址等数据,每个线程都有自己的栈,栈中的数据只能在本线程中可见。 |
本地方法栈(Native Method Stack) | 与栈类似,但是它是为本地方法服务的,即在 Java 中调用的本地方法。 |
程序计数器(Program Counter) | 记录当前线程执行的字节码指令地址,用于支持线程切换、方法调用、异常处理等功能。 |
与目前数组相关
的内存结构:
- 虚拟机栈(Stack):用于存放方法中声明的变量。例如,对于声明 int[] arr = new int[]{1,2,3}; 这一语句,arr 变量存放在栈中。
- 堆(Heap):用于存放数组的实体,即数组中的所有元素。例如,对于声明 int[] arr = new int[]{1,2,3}; 这一语句,数组中的元素 1, 2, 3 存放在堆中。
内容主要结构
举例1:基本使用
举例2:两个变量指向一个一维数组
多维数组使用
多维数组概述
如果说可以把一维数组当成几何中的
线性图形
,那么二维数组就相当于是一个表格
,像Excel中的表格、围棋棋盘一样。
- 某公司2021年全年各个
月份
的销售额进行登记。按月份存储,可以使用一维数组。如下:
int[] monthData = new int[]{23,43,22,34,55,65,44,67,45,78,67,66};
- 如果改写为按
季度
为单位存储怎么办呢?
int[][] quarterData = new int[][]{{23,43,22},{34,55,65},{44,67,45},{78,67,66}};
二维数组的定义
对于二维数组的理解,我们可以看成是一维数组array1又作为另一个一维数组array2的元素而存在。
二维数组的声明和初始化
声明
//推荐
元素的数据类型[][] 二维数组的名称;
初始化
二维数组元素调用
二维数组元素的长度
二维数组元素的遍历
二维数组的默认初始值
二维数组的内存解析
举例1:
举例2:
面试题合集
- JVM 内存分哪几个区,每个区的作用是什么?
- 方法区
- 有时候也成为永久代,在该区内很少发生垃圾回收,但是并不代表不发生 GC,
在这里进行的 GC 主要是对方法区里的常量池和对类型的卸载- 方法区主要用来存储已被虚拟机加载的类的信息、常量、静态变量和即时编译
器编译后的代码等数据。- 该区域是被线程共享的。
- 方法区里有一个运行时常量池,用于存放静态编译产生的字面量和符号引用。
该常量池具有动态性,也就是说常量并不一定是编译时确定,运行时生成的常量也
会存在这个常量池中。
- 虚拟机栈
- 虚拟机栈也就是我们平常所称的栈内存,它为 java 方法服务,每个方法在执行
的时候都会创建一个栈帧,用于存储局部变量表、操作数栈、动态链接和方法出口
等信息。- 虚拟机栈是线程私有的,它的生命周期与线程相同。
- 局部变量表里存储的是基本数据类型、returnAddress 类型(指向一条字节码指令的地址)和对象引用,这个对象引用有可能是指向对象起始地址的一个指针,也有可能是代表对象的句柄或者与对象相关联的位置。局部变量所需的内存空间在编译器间确定。
- 操作数栈的作用主要用来存储运算结果以及运算的操作数,它不同于局部变量表通过索引来访问,而是压栈和出栈的方式。
- 每个栈帧都包含一个指向运行时常量池中该栈帧所属方法的引用,持有这个引用是为了支持方法调用过程中的动态连接.动态链接就是将常量池中的符号引用在运行期转化为直接引用。
- 本地方法栈
本地方法栈和虚拟机栈类似,只不过本地方法栈为 Native 方法服务。
- 堆
java 堆是所有线程所共享的一块内存,在虚拟机启动时创建,几乎所有的对象实例
都在这里创建,因此该区域经常发生垃圾回收操作。
- 程序计数器
内存空间小,字节码解释器工作时通过改变这个计数值可以选取下一条需要执行的
字节码指令,分支、循环、跳转、异常处理和线程恢复等功能都需要依赖这个计数
器完成。该内存区域是唯一一个 java 虚拟机规范没有规定任何 OOM 情况的区域。