java虚拟机-02-运行时数据区

本贴最后更新于 4422 天前,其中的信息可能已经时移世改

      类加载后需要将数据保存到内存中,运行时也需要从内存中获取数据,从下图也可以看出运行时数据区是相当重要的一部分,这篇我们会介绍下java虚拟机是如何存储数据、数据是如何和其他模块交互的。

 

一、方法区
1、类被加载后的信息会被存储在方法区内,当程序运行时,虚拟机会查找并使用存储在方法区中的类信息。
2、存储的信息
     a、类:
         I、类的全限定名
         II、类的直接超类的全限定名
         III、类或是接口
         IV、类的访问修饰符
         V、任何直接超接口的全限定名的有序列表
    b、字段:
        I、字段名
        II、字段的类型
        III、字段的修饰符
    c、方法:
        I、方法名
        II、方法的返回类型
        III、方法参数的数量和类型(按声明顺序)
        IV、方法的修饰符
        V、如果方法不是抽象的和本地的,还需要保存

    • 方法的字节码
    • 操作数栈和该方法的栈帧中的局部变量区的大小
    • 异常表

    d、类静态变量
    e、常量池
3、方法表
为了提高访问效率,虚拟机对每个装载的非抽象类,都会生成一个方法表,把它作为的类信息的一部分保存在方法区。方法表是一个数组,它的元素是所有它的实例可能被调用的实例方法的直接引用,包括那些从超类继承过来的实例方法。运行时,可以通过方法表快速搜寻在对象中调用的实例方法的位置。

二、java堆
1、java程序运行时创建的所有类实例或数组都放在堆中。对象的回收由垃圾回收器自动回收,程序无法主动回收对象。
2、对象的数据由它所属的类和其所有超类声明的实例变量组成。它必须能通过该对象引用访问相应的类数据,因此对象中通常会有一个指向方法区中类的指针。
3、下图是堆的一种设计,吧堆分为两部分:一个句柄池,一个对象池,一个对象引用就是一个指向句柄池的本地指针。句柄池的每个条目由两部分:一个指向对象实例变量的指针,一个指向方法区类型数据的指针。

4、数组的存储如下图所示,数组类的名称由两部分组成,每一维用一个方括号“[”表示,用字符串或字符表示元素的类型。堆中的每个数组对象还必须保存数组的长度、数组数据,以及某些指向数组的类数据的引用。

 

三、程序计数器
对于一个运行中的java程序而言,其中的每一个线程都有他自己的pc寄存器,他是在该线程启动时创建的。pc寄存器的大小是一个字长,一次它既能够持有一个本地指针,也能够持有一个returnAddress。当线程执行某个java方法时,pc寄存器的内容总是下一条将被执行的指令的本地指针,也可以是在方法字节码中的相对于该方法的起始指令的偏移量。如果该线程正在执行一个本地方法,则此时pc寄存器的值是“undefined”。

四、java栈
1、每当启动一个新线程时,java虚拟机都会为它分配一个java栈。java栈是以帧为单位保存线程的运行状态。java栈只有两个操作:一帧为单位的压栈和出栈。某个线程正在执行的方法被称为该线程的当前方法,当前方法使用的栈帧称为当前帧,当前方法所属的类称为当前类,当前类的常量池称为当前常量池。
2、java方法可以以两种方式完成,一种通过返回return返回的,称为正常返回;一种是通过抛出异常而异常终止的。完成后虚拟机都会将当前帧弹出java栈然后释放掉,这样上一个方法的帧就成为当前帧了。

五、帧栈
1、帧栈由三部分组成:局部变量区、操作数据栈和帧数据区。局部变量区和操作数栈的大小要视对应的方法而定,它们是按字长计算买的。编译器在编译时就确定了这些值并放在了class文件中。而帧数据区的大小依赖于具体的实现。当虚拟机调用一个java方法时,他从对应类的类型信息中得到此方法的局部变量区和操作数栈的大小,并据此分配栈帧内存,然后压入java栈中。
2、局部变量区
局部变量区被组织为一个以字长为单位、从0开始计数的数组。包含对应方法的参数和局部变量。
3、操作数栈
操作数栈也是被组织成一个以字长为单位的数组。通过压栈和出栈来访问。虚拟机把操作数栈作为它的工作区,大多数指令都要从这里弹出数据,执行计算,然后把结果压回操作数栈。
4、帧数据区
    a、支持常量池解析:每当虚拟机要执行某个需要用到常量池数据的指令时,它都会通过帧数据区中指向常量池的指针来访问它。
    b、正常方法返回:帧数据区需要帮助虚拟机处理java方法的正常结束或异常终止。
    c、可以将一些其他的数据,比如调试数据放入到帧数据区中。

六、本地方法栈
当程序调用本地方法时,需要通过本地方法接口访问虚拟机的运行时数据区,而任何本地方法接口都会使用某种本地方法栈。当虚拟机调用一个本地方法时,虚拟机会保持java栈不变,不再在线程的java栈栈中压入新的帧,虚拟机只是简单的动态连接并直接调用指定的本地方法。

  • JVM

    JVM(Java Virtual Machine)Java 虚拟机是一个微型操作系统,有自己的硬件构架体系,还有相应的指令系统。能够识别 Java 独特的 .class 文件(字节码),能够将这些文件中的信息读取出来,使得 Java 程序只需要生成 Java 虚拟机上的字节码后就能在不同操作系统平台上进行运行。

    180 引用 • 120 回帖 • 1 关注
  • 编程
    52 引用 • 257 回帖 • 3 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • Gitea

    Gitea 是一个开源社区驱动的轻量级代码托管解决方案,后端采用 Go 编写,采用 MIT 许可证。

    5 引用 • 16 回帖 • 7 关注
  • Sandbox

    如果帖子标签含有 Sandbox ,则该帖子会被视为“测试帖”,主要用于测试社区功能,排查 bug 等,该标签下内容不定期进行清理。

    450 引用 • 1240 回帖 • 602 关注
  • 笔记

    好记性不如烂笔头。

    312 引用 • 794 回帖 • 1 关注
  • 尊园地产

    昆明尊园房地产经纪有限公司,即:Kunming Zunyuan Property Agency Company Limited(简称“尊园地产”)于 2007 年 6 月开始筹备,2007 年 8 月 18 日正式成立,注册资本 200 万元,公司性质为股份经纪有限公司,主营业务为:代租、代售、代办产权过户、办理银行按揭、担保、抵押、评估等。

    1 引用 • 22 回帖 • 818 关注
  • frp

    frp 是一个可用于内网穿透的高性能的反向代理应用,支持 TCP、UDP、 HTTP 和 HTTPS 协议。

    17 引用 • 7 回帖 • 5 关注
  • Dubbo

    Dubbo 是一个分布式服务框架,致力于提供高性能和透明化的 RPC 远程服务调用方案,是 [阿里巴巴] SOA 服务化治理方案的核心框架,每天为 2,000+ 个服务提供 3,000,000,000+ 次访问量支持,并被广泛应用于阿里巴巴集团的各成员站点。

    60 引用 • 82 回帖 • 625 关注
  • Firefox

    Mozilla Firefox 中文俗称“火狐”(正式缩写为 Fx 或 fx,非正式缩写为 FF),是一个开源的网页浏览器,使用 Gecko 排版引擎,支持多种操作系统,如 Windows、OSX 及 Linux 等。

    7 引用 • 30 回帖 • 363 关注
  • ngrok

    ngrok 是一个反向代理,通过在公共的端点和本地运行的 Web 服务器之间建立一个安全的通道。

    7 引用 • 63 回帖 • 662 关注
  • ZooKeeper

    ZooKeeper 是一个分布式的,开放源码的分布式应用程序协调服务,是 Google 的 Chubby 一个开源的实现,是 Hadoop 和 HBase 的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。

    61 引用 • 29 回帖 • 3 关注
  • H2

    H2 是一个开源的嵌入式数据库引擎,采用 Java 语言编写,不受平台的限制,同时 H2 提供了一个十分方便的 web 控制台用于操作和管理数据库内容。H2 还提供兼容模式,可以兼容一些主流的数据库,因此采用 H2 作为开发期的数据库非常方便。

    11 引用 • 54 回帖 • 677 关注
  • MongoDB

    MongoDB(来自于英文单词“Humongous”,中文含义为“庞大”)是一个基于分布式文件存储的数据库,由 C++ 语言编写。旨在为应用提供可扩展的高性能数据存储解决方案。MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。它支持的数据结构非常松散,是类似 JSON 的 BSON 格式,因此可以存储比较复杂的数据类型。

    91 引用 • 59 回帖 • 3 关注
  • 代码片段

    代码片段分为 CSS 与 JS 两种代码,添加在 [设置 - 外观 - 代码片段] 中,这些代码会在思源笔记加载时自动执行,用于改善笔记的样式或功能。

    用户在该标签下分享代码片段时需在帖子标题前添加 [css] [js] 用于区分代码片段类型。

    247 引用 • 1788 回帖 • 1 关注
  • Facebook

    Facebook 是一个联系朋友的社交工具。大家可以通过它和朋友、同事、同学以及周围的人保持互动交流,分享无限上传的图片,发布链接和视频,更可以增进对朋友的了解。

    4 引用 • 15 回帖 • 443 关注
  • 安全

    安全永远都不是一个小问题。

    201 引用 • 818 回帖
  • 周末

    星期六到星期天晚,实行五天工作制后,指每周的最后两天。再过几年可能就是三天了。

    14 引用 • 297 回帖
  • flomo

    flomo 是新一代 「卡片笔记」 ,专注在碎片化时代,促进你的记录,帮你积累更多知识资产。

    6 引用 • 143 回帖
  • Mac

    Mac 是苹果公司自 1984 年起以“Macintosh”开始开发的个人消费型计算机,如:iMac、Mac mini、Macbook Air、Macbook Pro、Macbook、Mac Pro 等计算机。

    167 引用 • 597 回帖 • 4 关注
  • CSDN

    CSDN (Chinese Software Developer Network) 创立于 1999 年,是中国的 IT 社区和服务平台,为中国的软件开发者和 IT 从业者提供知识传播、职业发展、软件开发等全生命周期服务,满足他们在职业发展中学习及共享知识和信息、建立职业发展社交圈、通过软件开发实现技术商业化等刚性需求。

    14 引用 • 155 回帖
  • ActiveMQ

    ActiveMQ 是 Apache 旗下的一款开源消息总线系统,它完整实现了 JMS 规范,是一个企业级的消息中间件。

    19 引用 • 13 回帖 • 698 关注
  • OkHttp

    OkHttp 是一款 HTTP & HTTP/2 客户端库,专为 Android 和 Java 应用打造。

    16 引用 • 6 回帖 • 95 关注
  • 印象笔记
    3 引用 • 21 回帖 • 2 关注
  • 机器学习

    机器学习(Machine Learning)是一门多领域交叉学科,涉及概率论、统计学、逼近论、凸分析、算法复杂度理论等多门学科。专门研究计算机怎样模拟或实现人类的学习行为,以获取新的知识或技能,重新组织已有的知识结构使之不断改善自身的性能。

    77 引用 • 37 回帖
  • API

    应用程序编程接口(Application Programming Interface)是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而又无需访问源码,或理解内部工作机制的细节。

    79 引用 • 431 回帖
  • Tomcat

    Tomcat 最早是由 Sun Microsystems 开发的一个 Servlet 容器,在 1999 年被捐献给 ASF(Apache Software Foundation),隶属于 Jakarta 项目,现在已经独立为一个顶级项目。Tomcat 主要实现了 JavaEE 中的 Servlet、JSP 规范,同时也提供 HTTP 服务,是市场上非常流行的 Java Web 容器。

    162 引用 • 529 回帖 • 8 关注
  • NGINX

    NGINX 是一个高性能的 HTTP 和反向代理服务器,也是一个 IMAP/POP3/SMTP 代理服务器。 NGINX 是由 Igor Sysoev 为俄罗斯访问量第二的 Rambler.ru 站点开发的,第一个公开版本 0.1.0 发布于 2004 年 10 月 4 日。

    316 引用 • 547 回帖
  • golang

    Go 语言是 Google 推出的一种全新的编程语言,可以在不损失应用程序性能的情况下降低代码的复杂性。谷歌首席软件工程师罗布派克(Rob Pike)说:我们之所以开发 Go,是因为过去 10 多年间软件开发的难度令人沮丧。Go 是谷歌 2009 发布的第二款编程语言。

    500 引用 • 1396 回帖 • 258 关注
  • GitBook

    GitBook 使您的团队可以轻松编写和维护高质量的文档。 分享知识,提高团队的工作效率,让用户满意。

    3 引用 • 8 回帖