文档章节

JVM之运行时数据区

Rhys_Lee
 Rhys_Lee
发布于 2016/07/15 11:50
字数 1318
阅读 19
收藏 0

Java虚拟机运行时数据区包括PC寄存器、Java虚拟机栈、Java堆、方法区、本地方法栈、运行时常量池六个部分。

1. PC寄存器

PC寄存器(又叫程序计数器,Program Counter Register),每一条Java虚拟机线程都有自己的PC寄存器。PC寄存器报错当前正在执行方法的字节码指令地址;如果当前方法是native的,则PC寄存器的值为undefined。

2. Java虚拟机栈

Java虚拟机栈(Java Virtual Machine Stack),每一条Java虚拟机线程都有自己私有的Java虚拟机栈,用于存储栈帧。

2.1 栈帧

栈帧(Frames)一种数据结构,用于存储局部变量和部分过程结果,也用于处理动态链接(Dynamic Linking)、方法返回值、异常分派(Dispatch Exception)。
栈帧随方法的调用创建,随方法的结束销毁(方法正常完成,抛出在方法内未捕获的异常都算做方法结束)。

每个栈帧拥有自己的局部变量表(Local Variables)、操作数栈(Operand Stack)和指向当前方法所属的类的运行时常量池的引用。

一个线程只有目前执行的方法的栈帧是活动的。这个栈帧就是当前栈帧,这个栈帧对应的方法就是当前方法,定义这个方法的类就是当前类。

当前栈帧正常执行完成后,还需要恢复调用者状态,包括调用者的局部变量表、操作数栈、和被正确增加过来表示执行了该方法调用指令的程序计数器等。

2.1.1 局部变量表

局部变量表(Local Variables)的长度由编译期决定,并存储在类或接口的二进制表示中--通过方法的Code属性保存并提供给栈帧使用。

一个局部变量可以保存类型为boolean、byte、char、short、float、reference和returnAddress的数据;两个局部变量可以保存类型为long、double的数据。

局部变量表通过索引访问,索引值从0开始。long或double占用两个连续的局部变量,使用较小的索引值来调用。当调用实例方法时,第一个局部变量(索引值0)用来存储被调用方法的对象引用(即this)。

2.1.2 操作数栈

操作数栈(Operand Stack)是一个后进先出(Last-In-First-Out)栈。操作数的长度由编译期决定,也存储在类或接口的二进制表示中,通过方法的Code属性保存并提供给栈帧使用。

操作数栈所属的栈帧在刚刚被创建时,操作数栈是空的。每个操作数栈的成员(Entry)可以保存一个Java虚拟机定义的任意数据类型的值,long和double也保存在一个成员中,成员是一个操作单位,但并不是一个存储单位,一个long或double类型的数据会占用两个单位的栈深度,其他数据类型占用一个。

在操作数栈中,一项运算常由多个子运算嵌套进行,一个子运算的过程的结果可以被其他外围运算使用。

2.1.3 运行时常量池的引用

每个栈帧都包含一个纸箱运行时常量池的引用,用于支持当前方法的代码实现动态链接(Dynamic Linking)。在Class文件中,描述一个方法调用了其他方法或者访问其成员变量是通过符号引用(Symbolic Reference)来表示的,动态链接的作用就是将这些符号引用所表示的方法转换为实际方法的直接引用。

3. Java堆

Java堆(Heap)是线程共享的,跟随Java虚拟机的生命周期。所有类实例和数组对象存储在堆中。

4.方法区

方法区(Method Area)是线程共享的,跟随Java虚拟机的生命周期。用于存储每一个类的结构信息,如运行时常量池、字段和方法数据、构造函数和普通方法的字节码内容、还包括一些在类、实例、接口初始化时用到的特殊方法(类或接口初始化方法<clinit>、实例初始化方法 <init>)

方法区是堆得逻辑组成部分,但是虚拟机可以不对这个区域进行垃圾回收(GC)。

5.运行时常量池

运行时常量池(Runtime Constant Pool)是每一个类或接口的常量池(Constant_Pool) [1],常量池保存了数值字面量、方法或字段的符号引用等。

每一个运行时常量池都分配在Java虚拟机的方法区中,在类或接口被加载到虚拟机后,对应的运行时常量池就被创建出来。

6.本地方法栈

本地方法栈(Native Method Stack)用来支持native方法的执行。和Java虚拟机栈类似也是跟随线程的生命周期。


  1. 常量池待详细整理

© 著作权归作者所有

共有 人打赏支持
Rhys_Lee

Rhys_Lee

粉丝 8
博文 10
码字总数 8778
作品 0
西城
高级程序员
私信 提问
JVM 运行时数据区简介及堆与栈的区别

理解JVM运行时的数据区是Java编程中的进阶部分。我们在开发中都遇到过一个很头疼的问题就是OutOfMemoryError(内存溢出错误),但是如果我们了解JVM的内部实现和其运行时的数据区的工作机制,...

大数据之路
2015/08/02
0
1
JVM(二)Java虚拟机组成详解

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

王磊的博客
01/14
0
0
JVM的方法区和永久带是什么关系?

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

若鱼1919
2018/07/26
0
0
经典面试题|讲一讲JVM的组成

JVM(Java 虚拟机)算是面试必问的问题的了,而但凡问 JVM 一定会问的第一个问题就是:讲一讲 JVM 的组成?那本文就注重讲一下 JVM 的组成。 首先来说 JVM 的组成分为,整体组成部分和运行时...

程序猿院长
04/15
0
0
001. 深入JVM学习—Java运行流程

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

影狼
2018/06/22
0
0

没有更多内容

加载失败,请刷新页面

加载更多

day11

architect刘源源
今天
7
0
论学好Linux系统的超级重要性

不知道各位在日常的工作生活中有没有接触过“rm -rf /*”这个命令,因为这个命令搞出来的事情可还不少呢!前段时间就在一个群里看到了有个小伙子,老板让他去维护一下服务器,这小伙也不太懂...

Linux就该这么学
昨天
6
0
git 使用

1,首先在github配置好信息和仓库,然后在本地进行操作 git init git config user.name 'zhangwuer' git config user.email '56789053@qq.com' 2,与远程分支建立连接 git checkout -b test......

天王盖地虎626
昨天
3
0
git checkout 命令详解

在日常的git操作中,git checkout——检出,是我们的常用命令。最为常用的两种情形是创建分支和切换分支。 在下面的命令中,使用了一些简写,在这里说明一下: git st # git statusgit ci ...

shzwork
昨天
11
0
【Nginx】Nginx多级代理,获取客户端真实请求IP以及每级代理IP

Nginx多级代理,获取客户端真实请求IP以及每级代理IP 如图所示,每一级nginx里的location配置里需要加上对应的配置,最后一级nginx是直接到应用,测试时为了方便,直接用echo模块去测试,打印...

薛定谔的旺
昨天
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部