2.5 运行时数据区域

  java虚拟机定义了多个用于程序执行期间的运行时数据区域。这些数据区域中一些随着java虚拟机的启动而创建,随着虚拟机的退出而销毁。其他的数据区域时和线程相关的。线程相关数据区域随着线程的创建而创建,随着线程的退出而销毁。

2.5.1 pc寄存器

  java虚拟机支持多个线程同时执行。每个线程拥有自己的pc(program counter)寄存器。在任何时刻,一个线程只会执行一个方法,即线程的当前方法。如果执行的方法不是本地(native)方法,pc寄存器包含当前正在执行的虚拟机指令的地址。如果当前线程执行的是本地方法,虚拟机的pc寄存器中的值是未定义的。Java虚拟机的pc寄存器足够保存一个一个特定平台上的returnAddress或本地指针。

2.5.2 java虚拟机栈

  每个线程都拥有一个私有的java虚拟机栈,和线程同时被创建。java虚拟机栈保存的栈是帧(frames)。java虚拟机栈和传统语言(比如c)的栈类似:它保存局部变量和部分结果,并在方法调用和返回中起作用。由于除了栈帧的入栈和出栈,Java虚拟机栈永远不会被直接操作,因此栈帧可以在堆中进行分配。Java虚拟机栈的内存不需要是连续的。

  本规范允许Java虚拟机堆栈具有固定大小或根据计算的需要动态扩展和收缩。如果Java虚拟机栈具有固定大小,则可以在创建该栈时独立选择每个Java虚拟机栈的大小。

  Java虚拟机的一个具体实现可以提供程序员或用户更改Java虚拟机栈初始大小的手段,以及在动态扩展或收缩Java虚拟机栈的情况下,控制最大和最小容量。

  虚拟机栈可能出现以下异常:

  •   如果一个线程需要的虚拟机栈大小超过允许的最大容量时,虚拟机栈将抛出stackOverflowError。
  •   如果java虚拟机栈可以动态扩展,并且当进行扩展时没有申请到足够的内存完成扩展,或者没有足够的内存为新线程创建虚拟机栈,则Java 虚拟机抛出OutOfMemoryError。

2.5.3 Java 堆

  Java虚拟机堆被所有的线程共享。java堆是运行时数据区域,用来分配类实例和数组的内存区域。

  java堆在虚拟机启动时创建。对象的堆存储由自动存储管理系统(称为垃圾收集器)回收;对象永远不会被显式释放。java虚拟机并不假定任何特定的自动存储管理系统类型,存储管理技术会根据实现者的系统需求来选定。堆可以是固定大小,或者根据需要扩展和压缩不需要的容量。堆使用的内存不需要时连续的。

  java堆和虚拟机栈类似,一个具体的实现可以提供开发者或者用户去控制堆的初始大小,也可以去控制一个动态扩展堆的最大和最小容量。

  下面的异常条件和堆有关:

  如果计算需要堆的容量超过了自动存储管理系统能给的最大容量,java虚拟机则抛出OutOfMermoryError。

2.5.4 方法区

  java虚拟机的方法区(method area)被所有Java虚拟机线程共享。方法区类似于传统语言的编译代码的存储区或类似于操作系统进程中的“文本”段。它存储每个类的结构,例如运行时常量池,字段和方法数据,以及方法和构造函数的代码,包括类和实例初始化以及接口初始化中使用的特殊方法。

  方法区在虚拟机启动时创建。尽管方法区在逻辑上是堆的一部分,但是简单的实现可以选择不进行垃圾回收和压缩。本规范未规定方法区域的位置或用于管理编译代码的策略。方法区可以是固定大小,或者根据需要扩展和压缩不需要的容量。堆使用的内存不需要时连续的。

  java虚拟机实现可以提供开发者或者用户去控制方法区的初始大小,也可以去控制一个动态扩展方法区的最大和最小容量。

  下面的异常条件和方法区有关:

  如果方法区的没有可用的内存去满足一次内存分配请求,java虚拟机会抛出OutOfMermoryError。

2.5.5 运行时常量池

  运行时常量池(run-time constant pool)是每一个类或者接口对应的class文件中constant_pool表的运行时表示形式。它包含几种常量,从编译时已知的数字的字面量到必须在运行时解析的方法和字段引用。运行时常量池提供类似于传统编程语言的符号表的功能,只是它包含比典型符号表范围更广的数据。

  每个运行时常量池都是分配在java虚拟机的方法区。当Java虚拟机加载类或接口时,将构造类或接口的运行时常量池。

  下面的异常条件和构建一个类或接口的运行时常量池有关:

  当加载一个类或者接口时,如果构建运行时常量池需要的内存超过java虚拟机方法区能够提供的最大容量,虚拟机将抛出OutOfMermoryError。

2.5.6 本地方法栈

  Java虚拟机的实现可以使用传统的栈,俗称“C stacks”,以支持本地方法(native methods)(用Java编程语言以外的语言编写的方法)。当Java虚拟机使用其他语言如C语言来实现java虚拟机指令集的解释器时,也可能用到本地方法栈。如果java虚拟机实现不能加载本地方法,它们自己也不需要依赖传统的栈,则没必要提供本地方法栈。如果支持的话,本地方法栈通常在线程创建的时候按照每个线程分配。

  本规范允许本地方法栈具有固定大小或根据计算的需要动态扩展和收缩。如果本地方法栈具有固定大小,则可以在创建该栈时独立选择每个本地方法栈的大小。

  java虚拟机实现可以提供开发者或者用户去控制本地方法栈的初始大小,也可以去控制一个支持动态扩展的本地方法栈的最大和最小容量。

  下面的异常条件和本地方法栈有关:

  •   如果一个线程需要的本地方法栈的容量超过允许的最大容量,那么虚拟机抛出StackOverflowError。
  •   如果本地方法栈支持动态扩展,当尝试扩展时没有足够的容量可用,或者没有足够的容量去为一个新线程创建一个初始的本地方法栈,java虚拟机抛出OutOfMemoryError。

  

java虚拟机规范(se8)——java虚拟机结构(二)的更多相关文章

  1. java虚拟机规范(se8)——java虚拟机结构(一)

    本文翻译自:https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html 第二章 虚拟机结构 本文档描述了一个抽象的虚拟机规范,并不描述 ...

  2. java虚拟机规范(se8)——java虚拟机结构(六)

    2.11 指令集简介 java虚拟机指令由一个字节的操作码,接着时0个或多个操作数组成,操作码描述了执行的操作,操作数提供了操作所需的参数或者数据.许多指令没有操作数只包含一个操作码. 如果忽略异常处 ...

  3. java虚拟机规范(se8)——java虚拟机的编译(四)

    3.12 抛出和处理异常 在程序中使用throw关键字来抛出异常.编译结果很简单. void cantBeZero(int i) throws TestExc { if (i == 0) { thro ...

  4. java虚拟机规范(se8)——java虚拟机的编译(一)

    本文翻译自:https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html 第三章 java虚拟机的编译 java虚拟机是设计用来支持ja ...

  5. java虚拟机规范(se8)——java虚拟机结构(三)

    2.6. 栈帧 栈帧用于存储数据和部分结果,同样也用于执行动态链接,返回方法的值和分派异常. 当方法被调用的时候会创建一个新的栈帧.当一个方法调用结束时,它对应的栈帧就被销毁了,不管是正常调用结束还是 ...

  6. java虚拟机规范(se8)——java虚拟机结构(五)

    2.10 异常 java虚拟机中的异常用Throwable类或者它的子类的实例来表示.抛出一个异常会导致立即非本地(an inmediate nolocal)的控制转移,从发生异常的地方跳到处理异常的 ...

  7. java虚拟机规范(se8)——java虚拟机结构(四)

    2.7 对象的表示 java虚拟机并不要求对象满足任何特定的内部结构. 在Oracle的一些Java虚拟机实现中,对类实例的引用是指向句柄的指针,该句柄本身是一对指针:一个指向包含对象方法的表和指向表 ...

  8. java虚拟机规范(se8)——java虚拟机的编译(二)

    3.3 算术运算 java虚拟机通常在操作数栈上进行算术运算(例外情况是iinc指令,它直接增加一个局部变量的值).例如下面的align2grain()方法,它的作用是将int值对齐到2的指定次幂: ...

  9. java虚拟机规范(se8)——java虚拟机的编译(三)

    3.6 接受参数 如果n个参数传给一个实例的方法,按照约定,它们被接受并放在这个新方法创建的栈帧中的局部变量表里,在局部变量表中的序号从1到n.这些参数按照它们传递过来的顺序存放.例如: int ad ...

随机推荐

  1. teamviewer & commercial-use

    teamviewer & commercial-use https://www.teamviewer.com/zhCN/pricing/commercial-use/ https://www. ...

  2. 移动的调试工具vConsole

    在PC端写代码调试的时候,直接console.log()即可,但是在手机端怎么调试??最近发现一个很有用的插件vConsole 首先引入插件: 然后再文件中使用即可: 这样再手机中就会出现下面的标识, ...

  3. 一本通1628X-factor Chain

    1628:X-factor Chain 时间限制: 1000 ms         内存限制: 524288 KB [题目描述] 原题来自 POJ 3421 输入正整数 x,求 x 的大于 1 的因子 ...

  4. [代码]--c#获取系统时间

    public DateTime GetServerDataTime() { string sql = " select top 1 getdate() from sysobjects &qu ...

  5. 【刷题】BZOJ 3745 [Coci2015]Norma

    Description Input 第1行,一个整数N: 第2~n+1行,每行一个整数表示序列a. Output 输出答案对10^9取模后的结果. Sample Input 4 2 4 1 4 Sam ...

  6. 【BZOJ1056】[HAOI2008]排名系统(Splay)

    [BZOJ1056][HAOI2008]排名系统(Splay) 题面 BZOJ 洛谷 题解 \(Splay\)随便维护一下就好了,至于名字什么的,我懒得手写哈希表了,直接哈希之后拿\(map\)压. ...

  7. BZOJ 4361 isn | DP 树状数组

    链接 BZOJ 4361 题面 给出一个长度为n的序列A(A1,A2...AN).如果序列A不是非降的,你必须从中删去一个数, 这一操作,直到A非降为止.求有多少种不同的操作方案,答案模10^9+7. ...

  8. 【bzoj2440】 中山市选2011—完全平方数

    http://www.lydsy.com/JudgeOnline/problem.php?id=2440 (题目链接) 题意 求第K个不含有完全平方因子的数 Solution 没想到莫比乌斯还可以用来 ...

  9. 【codevs1065】01字符串

    题目大意:输出仅由 0 和 1 组成的长度为 N 的字符串个数,并且其中不能含有 3 个连续的相同子串. 题解:数据太水,正规解法应该是枚举后缀进行判断. 代码如下 #include <bits ...

  10. ServiceStack.Redis 之 IRedisTypedClient<第四篇>

    IRedisTypedClient IRedisTypedClient类相当于IRedicClient的强类型版,其方法与属性大多数与IRedisClient类似. 它支持在Redis中使用Linq查 ...