一.Java的内存划分
Java的内存就像一间房子的划分一样,分为厨房,客厅,卧室。每个划分区域各司其职。Java的内存被划分为五个部分。
1.栈(Stack)
- 存放的都是方法中的局部变量。
- 方法的运行一定是在栈中的。
- 局部变量:方法的参数,或者是方法{}内部的变量。
- 局部变量的特点:有作用域,一旦超出作用域,就立刻从栈中消失。
2.堆(Heap)
- 凡是new出来的东西,都存在于堆中。
- 堆内存中的东西都有一个16进制的地址值。
- 堆内存里存放的数据都有默认的值;
—整数的默认值为0
—浮点数的默认值为0.0
—字符的默认值“\u0000”
—布尔的默认值false
—引用类型默认值为null
3.方法区(Method Area)
- 存储 .class 相关的方法,包含方法的信息。
- 有一个静态区存放静态数据
4.方法区(Native Method Stack)
- 与操作系统相关的信息
5.寄存器(pc Register)
- 与cpu相关的信息
二.数组的内存图
一个数组的内存图:
步骤如下
1. 在 .class 文件中找到main方法,并把main方法的头加载到方法区中。
2. 在方法区中寻找main方法的相关信息,把main方法的相关信息加载到栈中(方法运行都是在栈中的),并在栈中为main方法开辟一片区域。—进栈
3. int[ ] array = new int[3] 创建一个数组
int[ ] array : 首先把局部变量 int[] array 放在开辟的区域中,
new int[3]: new出来的东都在堆中,在堆中开辟一片区域放数组,并且划分为3个小格子。数组中存放的东西都要有默认值的,int类型的默认值为0。数组要有一个16进制的地址值(0x666)。这个地址值会被复制到 int[] array 后面。有了这个地址值,我们就可以找到堆中的数组。
4. System.out.println(array) 打印地址值。
5. System.out.println(array[0]) 先通array找到堆中数组的地址值(0x666),通过地址值找到堆中数组的位置,再通过索引找到数值。
6. array[1] = 10先找值(和5步骤一样),再修改。
两个独立数组的内存图: 就是做两遍一个数组的创建过程,没什么好说的。
两个引用指向同一个数组的内存图: 特别的地方在于在栈中, int[ ] arrayA 把地址值复制给了 int[ ] arrayB 。 arrayB[1] = 10 的操作步骤,先通过 int[ ] arrayB 后面的地址值,找到堆中数组的位置,再通过索引找到数值位置,再对数值进行修改。