一 、 JVM的内存分布
内存是一段连续的存储空间,主要用来存储程序运行时数据的。
- 程序运行时代码需要加载到内存
- 程序运行产生的中间数据要存放在内存
- 程序中的常量也要保存
- 有些数据可能需要长时间存储,而有些数据当方法运行结束后就要被销毁
JVM也对所使用的内存按照功能的不同进行了划分:
- 程序计数器 (PC Register):
只是一个很小的空间,
保存下一条执行的指令的地址。 - 虚拟机栈(JVM Stack): 与方法调用相关的一些信息,
每个方法在执行时,都会先创建一个栈帧,
栈帧中包含有:局部变量表、操作数栈、动态链接、返回地址以及其他的一些信息,
保存的都是与方法执行时相关的一些信息。
比如:局部变量。
当方法运行结束后,栈帧就被销毁了,
即栈帧中保存的数据也被销毁了。 - 本地方法栈(Native Method Stack):
本地方法栈与虚拟机栈的作用类似,
只不过保存的内容是Native方法的局部变量.
在有些版本的 JVM 实现中(例如HotSpot),
本地方法栈和虚拟机栈是一起的 - 堆(Heap):
JVM所管理的最大内存区域.
使用new 创建的对象都是在堆上保存,
堆是随着程序开始运行时而创建,
随着程序的退出而销毁,
堆中的数据只要还有在使用,就不会被销毁。 - 方法区(Method Area):
用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据.
方法编译出的的字节码就是保存在这个区域。
二 、 引用变量
1. 基本类型变量与引用类型变量的区别
基本数据类型创建的变量,称为基本变量,
该变量空间中直接存放的是其所对应的值;
引用数据类型创建的变量,一般称为对象的引用,
其空间中存储的是对象所在空间的地址。
public static void func() {
int a = 10;
int b = 20;
int[] arr = new int[]{1,2,3};
}
a、b、arr,都是函数内部的变量,
因此其空间都在main方法对应的栈帧中分配。
a、b是内置类型的变量,
因此其空间中保存的就是给该变量初始化的值。
array是数组类型的引用变量,
其内部保存的内容可以简单理解成是数组在堆空间中的首地址
引用变量并不直接存储对象本身,
可以简单理解成存储的是对象在堆中空间的起始地址。
通过该地址,引用变量便可以去操作对象。
2. 引用变量
publicstaticvoidfunc(){
int[]array1=newint[3];
array1[0]=10;
array1[1]=20;
array1[2]=30;
int[]array2=newint[]{1,2,3,4,5};
array2[0]=100;
array2[1]=200;
array1=array2;
array1[2]=300;
array1[3]=400;
array2[4]=500;
for(inti=0; i<array2.length; i++){
System.out.println(array2[i]);
}

- 空引用:null 在 Java 中表示 “空引用”, 也就是一个不指向对象的引用.null 的作用类似于 C 语言中的 NULL (空指针), 都是表示一个无效的内存位置. 因此不能对这个内存进行任何读写操作. 一旦尝试读写, 就会抛出 NullPointerException.
















