运行时数据区域
运行时数据区域说白了就是在虚拟机运行过程中,不同的数据(比如字节码.class数据,对象数据,native数据)所存放的区域是不一样的。什么区域放什么数据这都是有一定的规则的,这样有利于虚拟机管理,回收数据区域。
我经常会把运行时数据区域与java内存模型这两个概念搞混淆了,它俩完全是不同的概念。
java内存模型主要以屏蔽掉各种硬件和操作系统的内存访问差异,以实现让java程序在各种平台下都能达到一致的内存访问效果。建立原则:是围绕着在并发过程中如何处理原子性,可见性,有序性建立的。

上图展示了虚拟机运行时的数据区域划分:方法区,虚拟机栈,本地方法栈,Java堆,程序计数器。
方法区
方法区是线程共享的,看到这个名字怪怪的,大家应该会觉得这个区域主要是用来存放方法的,其实不然。它主要用于存放字节码数据,动态生成的字符串等。
字节码(class文件):是java编译后的产物,采用类似于c语言结构体的伪结构体来存储数据,这种伪结构体只有两种数据类型:无符号和表。类或接口中的变量方法都会对应各自的表,其中常量池是是占用空间大户(主要存放符号引用和utf字符)。
字节码经过加载,验证,准备,解析等流程后存放入方法区,最终会生成对应的Class对象(也存储于方法区)作为访问该类或接口的入口。
虚拟机栈
虚拟机栈是线程私有的,它的生命周期与线程同步,它描述的是java方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧(在debug调试代码的时候可以看到它),栈帧主要用于存储局部变量表,操作数栈,动态链接,方法出口等信息,每个方法从调用直至执行完成的过程就对应着一个栈帧在虚拟机栈从入栈到出栈的过程。
虚拟机栈总的来说就是存储当前线程所有的方法对应的栈帧。
本地方法栈
本地方法栈与虚拟机栈是非常相同的,区别在于虚拟机栈执行的是java方法,而本地方法栈执行的是native方法。
Java堆
Java堆是java虚拟机所管理的内存最大的一块,是所有线程共享的,它就是用来存放对象实例(所有的对象实例和数值几乎都分配于此)
Java堆是垃圾收集器管理的主要区域,从内存回收的角度来看,Java堆还可以细分为:新生代和老年代;再细致一点的有Eden空间,From Survivor空间,To
Survivor空间等。从内存分配的角度来看,线程共享的Java堆中可能划分出多个线程私有的分配缓存区(Thread Local Allocation Buffer,TLAB)。不过无论如何划分,存储的都是对象,进一步划分目的是为了更好的回收内存或者更快的分配内存。
程序计数器
程序计数器是线程私有的,它的主要作用是记录当前线程执行的位置在哪,以便于能恢复到原先执行位置。
网友评论