大家好,今天和大家分享java内存区域划分知识。

    通常我们把java的内存区域粗略划分为栈内存和堆内存,但是这只能说明程序员平常比较关心的是这两块内存,其实JAVA的内存划分却不止这两块内存,而要更加复杂一些。

    JAVA内存划分为以下几个区域:

                      

Java 内存根 java 内存区_JAVA

    1.程序计数器

    2.虚拟机栈

    3.本地方法栈

    4.方法区

    5.堆

    6.运行时常量池

    下面我们来逐个介绍:

1.程序计数器

    程序计数器是线程私有的一块内存,和线程绑定在一起,主要作用是存储当前线程所执行的字节码的行号。我们的JAVA语句,包括循环,异常处理等都要依赖这个计数器。但是需要注意的是,如果当前线程执行的JAVA方法,那么这个计数器记录的就是当前正在执行的虚拟机字节码指令的地址。如果执行的Native方法,那么这个计数器为空。

    2.虚拟机栈

    虚拟机栈也是线程私有的内存区域,虚拟机栈的作用主要是用来描述java方法执行的内存模型,每个方法在运行时都会在栈中创建一个栈帧,栈帧的作用主要是用来存储局部变量表,操作数栈,方法出口信息等,每个方法的执行实际就是栈帧在虚拟机栈中从入栈到入栈的过程。

    而我们平常讲的栈,就是说虚拟机栈,再详细一些,是指虚拟机栈中的局部变量表。

    在局部变量表中,我们存储的是编译期可知的基本数据类型和对象引用,以及returnAddress类型。

    其中对象引用并不是对象本身,对象本身存在于堆内存中,这里的对象引用可能是指向对象起始地址的引用指针,也可能是指向一个代表对象的句柄或者其他与实际对象相关的位置。而returnAddress则指向了一条字节码指令的地址。

    3.本地方法栈

    本地方法栈与虚拟机栈作用基本一样,只不过虚拟机栈是为虚拟机执行JAVA方法而作服务,但是本地方法栈服务的对象时Native方法。

    4.JAVA堆

    JAVA堆是虚拟机管理的最大的一块内存,是被线程共享的内存,该区域用于存储实例对象,几乎所有的对象都在这里进行内存分配。JAVA堆是垃圾收集器的主要工作区域,但是按照内存分配年代还可以细分为老年代和新生代,新生代也可以进行具体细分,这一点请参考我们之前的文章《JAVA垃圾回收过程》。但是JAVA堆并不要求是物理连续的内存区域,只要逻辑连续即可,与磁盘空间相似。

5.方法区

   方法区和堆内存一样,都是线程共享的内存区域,主要作用是用来存储被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据,有一些虚拟机实现将方法区实现为“永久代”,但是这并不是通用的做法,只是因为常见的HotSpot虚拟机将方法区将垃圾回收分代机制扩展至方法区。实际上方法区与永久代的概念并不一致。

    6.运行时常量池

    运行时常量池属于方法区的一部分,主要作用是存储在类加载后,将Class文件中用于存储编译期生成的各种字面量和符号引用的常量池。

    运行时常量池相对于Class文件中的常量池,显著的特点就是动态性,因为JAVA并不要求常量一定只有编译期才能产生,也就是并不只有Class文件中的常量池的内容才能存储在运行时常量池中,在运行期间,也可以将常量存储在池中。

    好了,以上就是JAVA中简单的内存区域划分,希望大家有所收获