深入理解java虚拟机之内存模型

程序计数器:

    程序计数器(Program Counter Register)是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器。在虚拟机的概念模型里(仅是概念模型,各种虚拟机可能会通过一些更高效的方式去实现),字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。

    由于Java虚拟机的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的,在任何一个确定的时刻,一个处理器(对于多核处理器来说是一个内核)都只会执行一条线程中的指令。因此,为了线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,各条线程之间计数器互不影响,独立存储,我们称这类内存区域为“线程私有”的内存。

     如果线程正在执行的是一个Java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行的是Native方法,这个计数器值则为空(Undefined)。此内存区域是唯一一个在Java虚拟机规范中没有规定任何OutOfMemoryError情况的区域。


虚拟机栈:

    我们常说的堆栈中的栈即指的这部分内存,虚拟机栈为线程私有,生命周期与线程相同,虚拟机栈一般来讲是存放方法中的变量的,每个方法对应一个栈帧,线程的栈中有很多栈帧,但是只有栈顶的栈帧是有效的,栈帧中存储着局部变量表,操作数栈,动态连接,方法出口等信息;

    局部变量表即保存方法中局部变量的表,其数据类型有八种基本数据类型,引用类型reference,和returnAddress(现已不常用,之前用于异常处理),局部变量表的最小空间是shot,long和double占用两个shot,其余的变量占用1个shot,局部变量表的空间在编译期间完全确定,运行期间不会改变局部变量表的大小;对于引用数据类型,reference,java虚拟机规范对其有两点要求,一可以找到其实例对象在堆中的地址,二可以匹配到其对应的方法区中的类的信息;

    局部变量表的空间大小在编译器已经确定,运行期间不会改变局部变量表的大小;局部变量表的shot是可以重复利用的,方法中有些变量的生命周期很短,在其使用结束之后,该shot被赋予新的值,这会对GC产生影响;

    操作数栈是方法中进行运算和赋值的内存,该空间为栈结构类型,先进后出;其空间大小在编译期已经确定;

    动态链接,每一个栈帧都保有对应于运行时常量池的方法的引用,持有该引用是为了支持方法调用中的动态链接;

    方法出口,即调用该方法的地址,在该方法结束后进行跳转;方法结束有两种方式, 一种是正常return,另一种是抛异常,如果是抛异常,将不会有返回值,而且返回的地址由异常处理器决定;

    虚拟机栈会抛出两种异常,对于单线程来讲,如果需要的栈空间大于实际的栈空间则会抛出StackOutflowError异常;如果存在可扩展的虚拟机栈,无法申请到足够的内存,则会抛出OutOfMemoryError;对于多线程,新的线程要分配栈空间,而如果内存已满,同样会抛出OutOfMemoryError;


本地方法栈:

    其作用域虚拟机栈很像,只不过这部分空间运行的是本地方法,其可能会抛出StackOutflowErrorOutOfMemoryError


java堆:

     一般来讲java堆是java内存模型中空间最大的地方,所有线程公用此区域,其主要功能是存放对象实例,即new出来的东西,都会放在堆中;java堆是垃圾回收器主要工作的地方,故也被称作GC堆,会抛出将会抛出OutOfMemoryError;


方法区:

    用于存放被虚拟机加载的类信息,常量,静态变量等数据,所有线程公用此区域,会抛出OutOfMemoryError异常;


运行时常量池:

    运行时常量池(Runtime Constant Pool)是方法区的一部分。Class文件中除了有类的版本、字段、方法、接口等描述信息外,还有一项信息是常量池(Constant Pool Table),用于存放编译期生成的各种字面量和符号引用,这部分内容将在类加载后进入方法区的运行时常量池中存放。会抛出OutOfMemoryError异常;

    这里区分一下常量池,字符串常量池,运行时常量池;

    常量池是Class文件的一部分,主要存放两大类内容,1字面量:文本字符串与final常量值,2符号引用,类或接口的全限定名,成员属性的名称和描述,方法的名称和描述

    字符串常量池:存储编译期类产生的字符串,jdk1.6之前在方法区中,jkd1.7之后在堆中

    运行时常量池:类加载后,存放类中常量池数据的地方,在方法区中;

   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值