【JVM规范】2.5.JVM运行时数据区 Run-Time Data Areas

2023-05-16

2.5.运行时数据区Run-Time Data Areas

JVM为程序执行定义了不同的运行时数据区( run-time data areas)。一部分运行时数据区在JVM启动时创建,JVM退出时被销毁。另一部分属于线程。线程数据区在线程创建事被创建,在线程退出时被销毁。

2.5.1. 程序计数器寄存器The pc Register

JVM支持多线程执行。每个JVM线程拥有自己的pc (program counter) 寄存器。在任何时候,每个Java虚拟机线程都在执行单个方法的代码,即该线程的当前方法(§2.6)。

如果该方法不是native方法,则pc寄存器包含当前正在执行的Java虚拟机指令的地址。如果线程当前正在执行的方法是native方法,则Java虚拟机的pc寄存器的值是未定义的。

Java虚拟机的pc寄存器足够宽,可以容纳特定平台上的返回地址(returnAddress)或本机指针(native pointer)。

2.5.2. Java虚拟机堆栈Java Virtual Machine Stacks

每个Java虚拟机线程都有一个私有的Java虚拟机堆栈,与线程同时创建。Java虚拟机堆栈存储栈帧frames(§2.6)。

Java虚拟机堆栈类似于C等传统语言的堆栈:它保存局部变量local variables和部分结果partial results。并在方法调用和返回中发挥作用。

因为,除了pushpop帧之外,Java虚拟机堆栈从不被直接操作。所以,帧可能是堆分配的。Java虚拟机堆栈的内存不需要连续。

该规范允许Java虚拟机堆栈要么大小固定,要么根据计算的需要动态扩展和收缩。如果Java虚拟机堆栈具有固定的大小(-Xss等价 -XX:ThreadStackSize),则当创建该堆栈时,可以独立地选择每个Java虚拟机堆栈的大小。

Java虚拟机实现可以为程序员或用户提供对Java虚拟机堆栈初始大小的控制,以及在动态扩展或收缩Java虚拟机堆栈的情况下,对最大和最小大小的控制。

以下异常情况与Java虚拟机堆栈相关联:

  • 如果线程中的计算需要比允许的更大的Java虚拟机堆栈,Java虚拟机将抛出StackOverflowError

  • 如果Java虚拟机堆栈可以动态扩展,并且尝试扩展但没有足够的内存来实现扩展;或者如果没有足够的内存来为新线程创建初始Java虚拟机堆栈。则Java虚拟机将抛出OutOfMemoryError错误。

2.5.3. 堆Heap


Java虚拟机有一个由所有Java虚拟机线程共享的堆。堆是运行时数据区,所有类实例和数组的内存都从这里分配。

堆是在虚拟机启动时创建的。对象的堆存储由自动存储管理系统(称为垃圾收集器garbage collector)回收对象永远不会被显式释放( objects are never explicitly deallocated.)。Java虚拟机假定没有特定类型的自动存储管理系统,并且可以根据实现者的系统需求来选择存储管理技术。堆的大小可以是固定的,也可以根据计算的需要进行扩展,如果不需要更大的堆,还可以进行收缩。堆的内存不需要连续。

Java虚拟机实现可以向程序员或用户提供对堆的初始大小的控制,并且如果堆可以动态扩展或收缩,还可以提供对最大和最小堆大小的控制。

以下异常情况与堆相关联:

  • 如果计算需要的堆超过了自动存储管理系统所能提供的堆,Java虚拟机就会抛出OutOfMemoryError

2.5.4. 方法区Method Area


方法区类似于传统语言的编译代码的存储区,或者类似于操作系统进程中的“文本”段。 它存储每个类的结构( per-class structures ),如运行时常量池( run-time constant pool)、字段( field)和方法数据( method data),以及方法和构造函数的代码( the code for methods and constructors),包括在类和实例初始化以及接口初始化中使用的特殊方法( §2.9)。

方法区域是在虚拟机启动时创建的。尽管方法区域在逻辑上是堆的一部分,但简单的实现可能选择不进行垃圾收集或压缩。该规范并不强制要求方法区域的位置或用于管理编译代码的策略。方法区域可以是固定的大小,或者可以根据计算的需要进行扩展,并且如果不需要更大的方法区域,可以进行收缩。方法区域的内存不需要连续。

Java虚拟机实现可以为程序员或用户提供对方法区域初始大小的控制,以及在可变大小的方法区域的情况下,对最大和最小方法区域大小的控制。

以下异常情况与堆相关联:

  • 如果方法区域中的内存无法满足分配请求,Java虚拟机将抛出OutOfMemoryError。OutOfMemoryError

2.5.5. 运行时常量池Run-Time Constant Pool


运行时常量池是类文件( 4.4)中constant_pool表的每个类或每个接口的运行时表示。它包含几种常量,从编译时已知的数字文字到必须在运行时解析的方法和字段引用。运行时常量池的功能类似于传统编程语言的符号表,尽管它包含的数据范围比典型的符号表更广。

每个运行时常量池都是从Java虚拟机的方法区域(2.5.4)中分配的。当Java虚拟机创建(5.3)类或接口时,构建类或接口的运行时常数池。

以下异常情况与类或接口的运行时常数池的构造相关联:

  • 当创建一个类或接口时,如果运行时常量池的构造需要比Java虚拟机的方法区域中可用的内存更多的内存,Java虚拟机将抛出OutOfMemoryError

有关运行时常量池构造的信息,请参见第5章(加载、链接和初始化)。

2.5.6. 本地方法堆栈Native Method Stacks


Java虚拟机的实现可以使用传统的栈,俗称“C栈”,来支持本地方法(用Java编程语言之外的语言编写的方法)。本地方法栈也可以被用诸如c语言的Java虚拟机指令集的解释器的实现使用。不能加载本地方法并且本身不依赖于传统堆栈的Java虚拟机实现不需要提供本地方法堆栈。如果提供了本机方法堆栈,通常会在创建每个线程时为每个线程分配。

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

Java虚拟机实现可以向程序员或用户提供对本地方法栈的初始大小的控制,以及在变化大小的本地方法栈的情况下,对最大和最小方法栈大小的控制。

以下异常情况与本机方法堆栈相关联:

  • 如果线程中的计算需要比允许的更大的本机方法堆栈,Java虚拟机将抛出StackOverflowError

  • 如果可以动态扩展本机方法堆栈,并且尝试扩展本机方法堆栈,但没有足够的可用内存,或者没有足够的可用内存来为新线程创建初始本机方法堆栈,则Java虚拟机将引发OutOfMemoryError

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【JVM规范】2.5.JVM运行时数据区 Run-Time Data Areas 的相关文章

  • JVM HotSpot 上的 Java 异常计数器

    我想知道是否可以在不更改应用程序代码的情况下记录 JVM 级别上发生的每个异常 我所说的每个异常是指捕获和未捕获的异常 我想稍后分析这些日志并按异常类型 类 对它们进行分组 并简单地按类型对异常进行计数 我正在使用热点 也许有更明智的理由这
  • 哪种语言(在 JVM 上运行)最适合创建 DSL?

    我们需要创建复杂的固定长度和可变长度字符串 这些字符串可能代表客户资料 订单等 你们建议使用哪种基于 JVM 的编程语言 想法是让最终用户使用此 DSL 创建字符串 所以我正在寻找验证 代码完成等 Groovy http docs code
  • 最近有关于 JVM 的书吗? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 比较ios中的两个时间值? [复制]

    这个问题在这里已经有答案了 在我的应用程序中 我想检查当前时间是在变量中保存的时间之前还是之后 就像我的时间1一样time1 08 15 12 我的时间2是time2 18 12 8 所以我想比较 time1 和 time2 目前这些变量是
  • 如何转换存储为两列(开始、结束)的日期范围以创建新行索引并填充值[重复]

    这个问题在这里已经有答案了 我想将存储为两列 开始 结束 值的日期范围转换为仅包含日期和值的两个新列 my data id end start value 1 4421 2014 01 01 2014 01 03 10 2 4421 201
  • 如何减少Scala中创建的对象数量?

    我正在 Scala 中编写一个计算机图形应用程序 它使用 RGB 类返回图像中某个点的颜色 正如你可以想象的 返回颜色 RGB 对象的函数被调用了很多次 class RGB val red Int val green Int val blu
  • Android 日期/时间显示 0 而不是 12

    我想知道下面的代码有什么问题 Assign hour set in the picker c set Calendar HOUR selectedHour c set Calendar MINUTE selectedMinute For a
  • 将正在运行的计数显示计时器添加到 iOS 应用程序中,例如时钟秒表?

    我正在使用一个应用程序 该应用程序可以处理设备运动事件并以 5 秒的增量更新界面 我想向应用程序添加一个指示器 以显示应用程序运行的总时间 看起来像秒表的计数器 例如本机 iOS 时钟应用程序 是计算应用程序运行时间并将其显示给用户的合理方
  • 什么触发了java垃圾收集器

    我对 Java 中垃圾收集的工作原理有点困惑 我知道当不再有对某个对象的实时引用时 该对象就有资格进行垃圾回收 但是如果它有对实时对象的引用怎么办 可以说我有一个节点集合 它们再次引用更多节点 List 1 gt Node a gt Nod
  • 在 JavaScript 中,如何让函数在特定时间运行?

    我有一个托管仪表板的网站 我可以编辑页面上的 JavaScript 目前每五秒刷新一次 我现在正在尝试获得window print 每天早上8点跑步 我怎么能这样做呢 JavaScript 是not用于此目的的工具 如果您希望某些东西在每天
  • 如何在 Microsoft Excel 中获取两个日期之间的分钟差?

    我正在 Excel 中做一些工作 遇到了一些问题 我正在使用的仪器保存测量的日期和时间 我可以使用以下格式将此数据读入 Excel A B 1 Date Time 2 12 11 12 2 36 25 3 12 12 12 1 46 14
  • 哪些语言可以很好地进行日期、时间和日历操作? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 这可能是一个过分的要求 但是有没有一种语言能够真正出色地表示时间和日期操作呢 我会立即承认这是真的很难编写一个真正伟大的时间库 也就是
  • Ruby 中的日期时间和时间之间的转换

    在 Ruby 中如何在 DateTime 和 Time 对象之间进行转换 require time require date t Time now d DateTime now dd DateTime parse t to s tt Tim
  • time() 会返回相同的输出吗?

    当用户注册时 我正在为 PHP 中的用户生成令牌 我想知道两个用户是否可以获得相同的令牌 因为这会破坏系统 请让我知道这是否足够 token md5 rand time 编辑 我现在正在使用我在另一个问题上找到的generate uuid
  • “马来半岛标准时间”的时区问题

    我有一个在 C 上运行以下代码的程序 TimeZoneInfo localZone TimeZoneInfo Local string timeZone TimeZoneInfo FindSystemTimeZoneById localZo
  • C 中经过的时间

    include
  • 如何将 currentTimeMillis 转换为可读的日期格式? [复制]

    这个问题在这里已经有答案了 我想用currentTimeMillis两次 这样我就可以计算持续时间 但我也想以用户可读的格式显示时间和日期 我遇到了麻烦currentTimeMillis有利于计算 但我看不到内置函数可以转换为合适的时间或时
  • 什么时候 Thread.sleep(1000) 睡眠时间少于 1000 毫秒?

    在这篇有趣的文章中程序员对时间的看法是错误的 http infiniteundo com post 25509354022 more falsehoods programmers believe about time wisdom 其中之一
  • Scala REPL 中的递归重载语义 - JVM 语言

    使用 Scala 的命令行 REPL def foo x Int Unit def foo x String Unit println foo 2 gives error type mismatch found Int 2 required
  • JVM内存段分配

    好吧 我有一个关于 JVM 内存段的问题 我知道每个 JVM 都会选择稍微不同地实现这一点 但这是一个总体概念 在所有 JVM 中应该保持相同 一个在运行时不使用虚拟机执行的标准C C 程序在运行时有四个内存段 代码 堆栈 堆 数据 所有这

随机推荐