Java运行时数据区

19 篇文章 0 订阅

在《Java虚拟机规范》中,将Java运行时数据区分为六个部分:PC计寄存器,Java虚拟机栈,Java堆,方法区,运行时常量池,本地方法栈。

PC寄存器

PC寄存器(Program Counter Register),在大学期间《计算机体系结构》这门课中有介绍过这个概念,简单地讲可以看做是指向当前执行指令的指示器,在Java虚拟机中,这个概念也类似,如果线程正在执行一个Java方法,那么它指向的正是这个指令的地址。如果该方法不是native的,那么pc寄存器就保存JVM正在执行的字节码指令的地址,如果是native的,那么pc寄存器的值为undefined。

Java虚拟机栈

每条Java虚拟机线程都私自拥有Java虚拟机栈(Java Virtual Machine stack),在创建线程的同时也创建Java虚拟机栈。与我们常规理解的栈类似,也是保存一些还没计算好的结果,例如递归调用就是属于这种场景。另外一点Java虚拟机栈分配内存是不需要连续的。

在Java虚拟机规范中,Java虚拟机栈可以是固定大小的,也可以根据实际需求来动态调整栈的大小。

我们一般熟悉的两种异常StackOverFlowErrorOutOfMemoryError就是Java虚拟机栈上很可能出现的两种异常,当然这两种异常出现的情况是不同的,如果线程请求分配的栈容量超过Java虚拟机栈允许的最大容量,那么就抛出StackOverFlowError的异常,如果Java虚拟机栈需要动态扩展,但是扩展的过程中无法分配足够的内存,那么就抛出OutOfMemoryError异常。

Java堆

在Java虚拟机中,堆正是为所有类实例和数组对象分配内存的区域,而且此区域可供线程共享。Java堆是在虚拟机启动的时候创建的,同样也是在这个区域上进行大名鼎鼎的GC(垃圾回收)操作,同Java虚拟机栈类似,该区域的大小可以是固定的,也可以动态调整,而且也不需要内存必须是连续的。如果实际所需要的内存超过了所提供的的最大容量,那么JVM也会抛出OutOfMemoryError的异常。

方法区

方法区也可以共享给各个线程,它存储了每一个类的结构信息,比如字段,方法数据,构造函数和普通方法的字节码等,还有一些类、实例、接口初始化时用到的一些特殊方法。

方法区也是在虚拟机启动的时候创建的,虽然方法区再逻辑上是属于Java堆的一部分,但是在这个区域上可以不用实现垃圾回收等功能。而且方法区的大小也是可以固定的,当然也可以根据实际需求进行调整,同样也不要求内存空间必须连续。

运行时常量池

运行时常量池又是方法区的一部分,所以每个运行时常量池都在Java虚拟机的方法区中进行分配,在加载类和接口到虚拟机后,就创建对应的运行时常量池。一般而言,除了保存Class文件中描述的符号引用外,还会把翻译出来的直接引用也存储在运行时常量池中。同样,当创建接口或者类时,如果超出了方法区所能提供的最大值,那么也会抛出OutOfMemoryError的异常。

本地方法栈

Java虚拟机可能使用我们传统意义上的栈来支持一些native方法,这就是本地方法栈。所以从某种意义上讲,本地方法栈与Java虚拟机栈差不多,唯一的区别就是服务对象不同,也就是Java虚拟机栈服务Java方法,本地方法栈服务native方法。而且也是大小可固定可调整,内存也不是必须连续的。抛出异常的情况与Java虚拟机栈是一样的。

参考文献

  1. 《The Java Virtual Machine Specification——Java SE 8》,Tim Lindholm,Frank Yellin,Gilad Bracha,Alex Buckley。
  2. 《深入理解Java虚拟机——JVM高级特征与最佳实践 第二版》,周志明,机械工业出版社。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值