文档章节

Java虚拟机运行时数据区结构

foodon
 foodon
发布于 2014/12/09 15:51
字数 959
阅读 322
收藏 14

本文部分参考自《Java虚拟机规范(Java SE 7版)》的中译本和周志明的《深入理解Java虚拟机》,另加个人理解。原书对Java虚拟机运行时数据区描述只有6页,同时参考其他网络网资料,个人能力所限,不排除存在认知错误。

JVM将程序运行期间使用的内存划分为若干个运行时数据区,其中一些会随着虚拟机启动而创建,随着虚拟机退出而销毁。另外一些与线程一一对应,随着线程开始而创建,随着线程结束而销毁。数据区划分如下图所示意:

Java堆(Java Heap)

在JVM中,Java堆是可供各个线程共享的运行时内存区域,是供所有类实例和数组对象分配内存的区域。Java堆在虚拟机启动时被创建,存储了垃圾收集器(GC)管理的各种对象,这些对象无法显式销毁。

Java堆可能发生OutOfMemoryError错误。

方法区(Method Area)

方法区用于存储已被虚拟机加载的类的结构信息,例如:运行时常量池、字段和方法数据、构造函数和普通方法的字节码,还包括一些在类、实例、接口初始化时用到的特殊方法。

方法区逻辑上是Java堆的一部分,但JVM规范对方法区限制非常宽松,可以选择不实现垃圾收集。实际因为类型卸载的条件非常苛刻,方法区的垃圾收集效果也不理想。

方法区可能发生OutOfMemoryError错误。

运行时常量池(Runtime Constant Pool)

每个类或接口的字节码中去了有类的版本、字段、方法、接口等描述信息外,还包含一个常量池表(constant_pool table),用于存放编译期生成的各种字面值和符号引用,运行时常量池是这个常量池表的运行时表示形式。每个运行时常量池都在JVM的方法区中分配,在加载类和接口到虚拟机后,就创建对应的运行时常量池。

在创建运行时常量池时,JVM可能会抛出OutOfMemoryError错误。



PC计数器(Program Counter Register)

JVM线程私有,保存当前线程正在执行的字节码指令的地址,如果正在执行的是Native方法,值为undefined,本内存区域没有规定内存错误。

Java虚拟机栈(Java Virtual Machine Stack)

在第一版中也称为Java Stack,每一条JVM线程都有自己私有的Java虚拟机栈,这个栈与线程同时创建,用于存储栈帧(Frame)。

Java虚拟机栈可能发生StackOverFlowError和OutOfMemoryError错误。

本地方法栈(Native Method Stack)

JVM线程私有,和Java虚拟机栈作用类似,Java虚拟机栈为虚拟机执行Java方法服务,而本地方法栈为虚拟机执行Native方法服务。JVM规范没有规定本区域如何实现,Sun HotSpot虚拟机直接把本地方法栈和Java虚拟机栈合成了一个。和Java虚拟机栈一样,本地方法栈也可能抛出StackOverFlowError和OutOfMemoryError错误。

栈帧(Stack Frame)


栈帧是用于存储数据和部分过程结果的数据结构,每次方法调用对应一个栈帧,随着方法调用而创建,随着方法结束而销毁。栈帧的空间分配在Java虚拟机栈中,每个栈帧包括自己的本地变量表、操作数栈和动态链接(指向当前方法所属类的运行时常量池的引用)。



© 著作权归作者所有

共有 人打赏支持
foodon
粉丝 59
博文 56
码字总数 27005
作品 0
海淀
技术主管
私信 提问
加载中

评论(4)

ddoer
ddoer
“修改PC Register的值为$lineno”这个地方我描述的有问题,应该是修改PC Register的值为$lineno行指令的地址。
ddoer
ddoer

引用来自“ddoer”的评论

请教:我看有书上这样描述PC计数器,“字节码解释器工作时,就是通过改变程序计数器的值来选取下一条要执行的指令,分支、循环、跳转、异常处理等基础功能都是依赖此计数器完成的”,这样说来,PC计数器存储的到底是当前指令的地址,还是下条指令的地址?能解释下吗,或者给个方向,我再查资料,谢谢

引用来自“foodon”的评论

我的理解是下一条。
我想了下,这个需要看分支、循环、跳转、异常处理、函数调用返回等是如何实现的,对for循环,用javap -c查看字节码,可以看到循环使用的是goto $lineno,猜测是执行goto的时候,修改PC Register的值为$lineno,具体实现原理,还需要确认。
foodon
foodon

引用来自“ddoer”的评论

请教:我看有书上这样描述PC计数器,“字节码解释器工作时,就是通过改变程序计数器的值来选取下一条要执行的指令,分支、循环、跳转、异常处理等基础功能都是依赖此计数器完成的”,这样说来,PC计数器存储的到底是当前指令的地址,还是下条指令的地址?能解释下吗,或者给个方向,我再查资料,谢谢
我的理解是下一条。
ddoer
ddoer
请教:我看有书上这样描述PC计数器,“字节码解释器工作时,就是通过改变程序计数器的值来选取下一条要执行的指令,分支、循环、跳转、异常处理等基础功能都是依赖此计数器完成的”,这样说来,PC计数器存储的到底是当前指令的地址,还是下条指令的地址?能解释下吗,或者给个方向,我再查资料,谢谢
JVM(二)Java虚拟机组成详解

导读:详细而深入的总结,是对知识“豁然开朗”之后的“刻骨铭心”,想忘记都难。 Java虚拟机(Java Virtual Machine)下文简称jvm,上一篇我们对jvm有了大体的认识,进入本文之后我们将具体...

王磊的博客
01/14
0
0
Java虚拟机JVM内部体系结构

Java虚拟机JVM内部体系结构 易百教程移动端:请扫描本页面底部(右侧)二维码并关注微信公众号,回复:"教程" 选择相关教程阅读或直接访问:http://m.yiibai.com 。 JVM(Java虚拟机)是一个抽象...

LYQ1990
2018/07/18
0
0
JVM规范系列第2章:Java虚拟机结构

本规范描述的是一种抽象化的虚拟机的行为,而不是任何一种(译者注:包括 Oracle 公司自己的 HotSpot 和 JRockit 虚拟机)被广泛使用的虚拟机实现。 记住:JVM规范是一种高度抽象行为的描述,...

陈树义
2018/12/19
0
0
JVM的方法区和永久带是什么关系?

群里面有小伙伴问到这个问题,说在网上看了很多文章,但是还是没弄明白这俩是啥关系,下面我们就来详细的解释一下: 什么是方法区? 方法区(Method Area)是jvm规范里面的运行时数据区的一个...

若鱼1919
2018/07/26
0
0
001. 深入JVM学习—Java运行流程

Java运行流程图 2. Java运行时数据区 3. Java虚拟机栈 栈内存是线程私有的,其生命周期和线程相同; 虚拟机栈描述的是Java方法执行的内存模型:执行一个方法时会产生一个栈帧随后将其保存到栈...

影狼
2018/06/22
0
0

没有更多内容

加载失败,请刷新页面

加载更多

阿里的Java岗面试到底有多难?这些常问技术原理你能答出多少!

阿里面试喜欢问哪些? 阿里的面试特别喜欢面试技术原理,特别是 数据结构 多线程并发 NIO 异步消息框架 分布式相关的缓存算法等 JVM的加裁过程和原理 垃圾回收算法 以及具体使用过的框架,会...

java知识分子
5分钟前
0
0
hibernate入门

下载和导包 下载hibernate 导入数据库驱动包 导入hibernate必要包 lib/required 导入日志记录的包 创建数据库和数据库实体 package com.company.domain;public class Customer { ...

gwl_
11分钟前
0
0
快速体验 Sentinel 集群限流功能,只需简单几步

️ Pic by Alibaba Tech on Facebook 集群限流 可以限制某个资源调用在集群内的总 QPS,并且可以解决单机流量不均导致总的流控效果不佳的问题,是保障服务稳定性的利器。 Sentinel 从 1.4.0 ...

阿里云云栖社区
11分钟前
0
0
元数据注册系统:命名和标识原则

名词定义 对象类术语 对象类是概念、抽象或客观事物的集舍,它们具有明确的边界和含义,且其特性和行为都遵循相同的规则。一个对象类术语可以是管理项概念域、数据元概念和数据元的名称的一部...

十动然拒
20分钟前
0
0
抽丝剥茧:生产环境中负载均衡产品DPDK问题的解决

ULB4是UCloud自主研发的基于DPDK的高可用四层负载均衡产品,转发能力接近线速;DPDK则是一个高性能的开源数据面开发套件。ULB4作为用户应用的全局入口,在大流量多元化场景下保证用户业务的持...

UCloudTech
21分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部