1.1. 内存配置
Java的内存划分分为5个部分:
1) 虚拟机栈(VS Stack)
虚拟机栈表示Java方法执行的线程内存模型,线程每调用一个方法就会为每个方法生成一个栈帧(Stack Frame),用来存储本地变量表、操作数栈、动态链接、方法出口等信息。每个方法被调用和完成的过程,都对应一个栈帧从虚拟机栈上入栈和出栈的过程。虚拟机栈的生命周期和线程是相同的
局部变量:方法的参数,或是方法{}内部的变量。
作用域:一旦超出作用域,立即从栈的内存中消失。
2)堆(Headp)
凡是new出的东西均存放在堆中,也就是存储的对象,对象包含类的信息存放在方法区。
PS:1)堆中存放的内容具有个地址值,是16进制的。2)堆里面的内容具有默认值。
3)方法区(Method Aera)
存储.class相关信息,包含方法的信息;编译后的代码;运行时常量池;静态区;
4)本地方法栈(Netive Method Stack)
与操作系统有关,一个支持native方法调用的JVM实现
5)寄存器(PC Register)
与CPU有关,用来记录当前正在执行的指令
1.2. 运行时的栈帧结构
线程中的内存配置如下图所示:
1.2.1. 栈帧
栈帧(stack frame)是用于支持虚拟机进行方法调用和方法执行的数据结构,它是虚拟机运行时数据区中的虚拟机栈的栈元素。栈帧存储了方法的本地变量表、操作数栈、动态连接和方法返回地址等信息。每一个方法从调用开始到执行完成的过程,就对应着一个栈帧在虚拟机栈里面从入栈到出栈的过程。
对于执行引擎来说,活动线程中,只有栈顶的栈帧是有效的,称为当前栈帧,这个栈帧所关联的方法称为当前方法。执行引擎所运行的所有字节码指令都只针对当前栈帧进行操作。
1.2.2. 本地变量表
1)本地变量表的作用
本地变量表是一组变量值存储空间,用于存放方法参数和方法内部定义的局部变量。
2)变量存放方式
局部变量都是以变量槽(Slot)的形式存放。
局部变量表存放了编译器可知的java虚拟机数据类型,可以保存类型为基本数据类型(byte, char, short, int, long, float,double)、对象引用类型(reference)。其中double和long会占用两个变量槽,其他的都是占用一个变量槽,而变量槽的大小是32byte还是64byte,这是由虚拟机决定的,不同虚拟机可能不一样。
3)线程安全问题
本地变量表建立在线程的堆栈上面,线程私有的,无论读写两个连续的Slot是否为原子操作,都不会引起数据安全问题。
4) 栈帧内存空间的确定
在程序编译完成生成class文件之后,其实就已经确定了本地变量表的大小,以及操作数栈