虚拟机内存划分

一、内存划分:
首先Java源代码文件(.java后缀)会被Java编译器编译为字节码文件(.class后缀),然后由JVM中的类加载器加载各个类的字节码文件,加载完毕之后,交由JVM执行引擎执行。在整个程序执行过程中,JVM会用一段空间来存储程序执行期间需要用到的数据和相关信息,这段空间一般被称作为Runtime Data Area(运行时数据区),也就是我们常说的JVM内存。因此,在Java中我们常常说到的内存管理就是针对这段空间进行管理(如何分配和回收内存空间)。
在这里插入图片描述
首先,堆和方法区是所有线程共享的内存区域,而虚拟机栈和本地方法栈以及程序计数器是线程隔离的数据区。
1、程序计数器(唯一一个在规范中没有规定任何OutOfMemoryError的区域):
在汇编语言中,程序计数器是指CPU中的寄存器,它保存的是程序当前执行的指令的地址(也可以说保存下一条指令的所在存储单元的地址),当CPU需要执行指令时,需要从程序计数器中得到当前需要执行的指令所在存储单元的地址,然后根据得到的地址获取到指令,在得到指令之后,程序计数器便自动加1或者根据转移指针得到下一条指令的地址,如此循环,直至执行完所有的指令。
而且由于java虚拟机的多线程是通过线程切换并分配处理器执行时间的方式来实现的,在任何一个确定的时刻,一个处理器都只会执行一条线程中的指令。所以为了线程切换后能恢复到正确的执行位置,每条线程都需要一个独立的程序计数器来记录所执行的字节码的行号。
如果线程正在执行java方法,该计数器记录的是正在执行的虚拟机字节码指令的地址。如果正在执行的Native方法,该计数器则为空。
由于程序计数器中存储的数据所占空间的大小不会随程序的执行而发生改变,因此,对于程序计数器是不会发生内存溢出(OutOfMemoryError)

2.虚拟机栈:
生命周期与线程相同,描述的是Java方法执行的内存模型。
虚拟机栈中存放的是一个个栈帧,每一个栈帧对应一个被调用的方法。栈帧用于存储局部变量表、操作数栈、动态链接、方法出口等信息。当线程执行一个方法时,就会随之创建一个对应的栈帧,并将建立的栈帧压栈。当方法执行完毕之后,便会将栈帧出栈。因此可知,线程当前执行的方法所对应的栈帧必定位于Java栈的顶部。
局部变量表:存储方法中的局部变量(包括在方法中声明的非静态变量以及函数形参)、存放编译期可知的各种基本数据类型(八大)、对象引用、返回地址类型。所需的内存空间在编译期就完成了分配。

3、本地方法栈:
与虚拟机栈所发挥的作用非常相似,只是本地方法栈为使用到的Native方法服务。在JVM规范中,并没有对本地方发展的具体实现方法以及数据结构作强制规定,虚拟机可以自由实现它。在HotSopt虚拟机中直接就把本地方法栈和Java栈合二为一。

4、Java堆:
在C语言中,堆这部分空间是唯一一个程序员可以管理的内存区域。程序员可以通过malloc函数和free函数在堆上申请和释放空间。
在Java中,是虚拟机所管理的内存中最大的一块。就是为了存放对象实例以及数组。(数组引用存放在Java栈中)。也是垃圾回收的主要区域。

5、方法区:
也是各个线程共享的内存区域,用于存储被虚拟机加载的类信息、常量、静态变量等数据。
运行时常量池也是方法区的一部分,用于存放编译期生成的各种字面量和符号引用。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值