-
定义
Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域
image.png
-
类型
线程共享内存区:方法区、堆
线程独有内存区:虚拟机栈、本地方法栈、程序计数器
注意:线程共享内存区就是我们常要考虑内存回收的地方、而线程独有内存区是会随着线程的执行结束而消亡的,不需要考虑内存回收
![](https://img.haomeiwen.com/i12474664/2c0c817737196638.png)
1、方法区:
用于储存静态变量、常量、已经被虚拟机所加载的类信息(我们可以理解为已经java代码被虚拟机编译成的.class文件)
2、堆:
堆内存用来存储Java中的对象,几乎所以的对象都存储在堆中,无论是成员变量,局部变量,还是类变量,它们指向的对象都存储在堆内存中,堆内存中的对象对所有线程可见。堆内存中的对象可以被所有线程访问。也是垃圾回收的主要区域。
3、虚拟机栈:
存储当前线程运行方法所需的数据,指令、返回地址
以栈帧的方式存储方法调用的过程,并存储方法调用过程中基本数据类型的变量(int、short、long、byte、float、double、boolean、char等)以及对象的引用变量(这里其实就是堆中对象的引用),其内存分配在栈上,变量出了作用域就会自动释放;栈内存归属于单个线程,每个线程都会有一个栈内存,其存储的变量只能在其所属线程中可见,即栈内存可以理解成线程的私有内存。
- 注意:虚拟机栈里每个方法之执行的时候都会创建一个栈帧,栈帧又可以划分为:操作数栈、局部变量表、返回地址、动态链接(在多态中,寻找引用所指向的对象的时候会用到)
4、本地方法栈:
保存的是native方法的信息。
5、程序计数器:
指向当前线程运行的字节码指令的地址(行号)
现在我们来举个列子说明下:
//常量
final String Fs ="常在河边走,哪有不湿鞋";
//静态变量
static String Ss ="以静制动";
//次数
int count =0 ;
public void king(int money){
//13号妓师
Object tech13 = new Object();
//调用一次13号服务
tech13.hashCode();
int i;
money = money -100; //花费100
count++;
//if(count ==2000) return;
king(money);
}
![](https://img.haomeiwen.com/i12474664/326863320fbcb6fc.png)
当上面这段java代码运行的时候,jvm会把这段java代码反编译成.class文件,并在内存中开辟一块运行时数据区,然后把运行时数据区域分成方法区、堆、虚拟机栈、本地方法栈、程序计数器几块区域。
1、方法区中的数据: final String Fs 、static String Ss
2、堆中的数据: Object tech13, int count
3、虚拟机栈:king方法中的入参:int money,king方法里的局部变量int i;
tech13对象的引用
4、本地方法栈:当调用tech13.hashCode()时,因为hashCode是native方法,所以是在本地方法栈保存hashCode方法的信息的。
public native int hashCode();
当前线程里有一个方法时,虚拟机栈里会创建一个栈帧,上面这段方法是有一个king()方法,所以会在虚拟机栈里创建一个栈帧,如果比如还有king2,king3方法就会创建3个栈帧,但每个栈帧里的结构是差不多的,操作数栈里会进行count++类似于这样的操作,局部变量表里就是存储运行方法时所需要的基本数据类型的变量(例如int i,int money)及所需要的对象的引用(例如tech13对象的引用,和自身this对象的引用),但实际的tech13对象时存储在堆里的。
6、深入辨析堆和栈
- 以栈帧的方式存储方法调用的过程,并存储方法调用过程中基本数据类型的变量(int、short、long、byte、float、double、boolean、char等)以及对象的引用变量,其内存分配在栈上,变量出了作用域就会自动释放;
- 而堆内存用来存储Java中的对象。无论是成员变量,局部变量,还是类变量,它们指向的对象都存储在堆内存中;
线程独享还是共享
- 栈内存归属于单个线程,每个线程都会有一个栈内存,其存储的变量只能在其所属线程中可见,即栈内存可以理解成线程的私有内存。
- 堆内存中的对象对所有线程可见。堆内存中的对象可以被所有线程访问。
空间大小
- 栈的内存要远远小于堆内存,栈的深度是有限制的,可能发生StackOverFlowError问题(如果方法里调方法递归调用时)。
网友评论