【深入理解Java虚拟机】内存管理和对象访问

2023-10-31

一:JVM内存区域划分

在这里插入图片描述
(1)程序计数器(线程私有):类似于eclipse中断点程序(行号指示器),记录了程序下一步需要执行的字节码指令,分支,循环等分支。线程私有,每个线程有一个程序计数器
程序计数器是为了多线程情况下,线程执行切换后,处理器回来原来线程能找到之前线程执行的位置
若执行Java方法,计数器记录是是正在执行的虚拟机字节码指令的地址,
若执行Native方法,这个计数器为空,此内存区域是唯一一个在Java虚拟机规范中没有规定任何OutOfMemoryError情况的区域。
(2)java虚拟机栈(栈内存,线程私有):执行java方法,生命周期与线程相同,每个方法在执行时会创建一个栈帧(Stack Frame)用于存储局部变量表,操作数栈,动态链接,方法出口等信息。
局部变量表存放:各种基本数据类型,对象应用,returnAddress类型。
其中64位长度的long和double类型的数据会占用2个局部变量空间(Slot),其余的数据类型只占用1个。局部变量表所需要的内存空间在编译期间完成分配,当进入一个方法时,这个方法需要在帧中分配多大的局部变量的空间是完全确定的,在方法运行期间不会改变局部变量表的大小。
(3)本地方法栈:允许的是 native 关键字标识的方法,可有虚拟机自由实现。
(4)堆内存(所有线程共享):虚拟机启动时创建,存放对象实例和数组。随着JIT编译器的发展和逃逸分析技术逐渐成熟,栈上分配,标量替换优化技术将会导致一些微妙变化,所有的对象都分配在堆上也逐渐变得不是那么“绝对”了。 堆是垃圾回收的主要区域,堆会根据不同的垃圾回收机制进行划分。
(5)方法区(所有线程共享):存储已被虚拟机加载的类信息,常量,静态变量,JIT编译器编译后的代码等数据。虽然Java虚拟机规范把方法区描述为堆的一个逻辑部分,但是它却有一个别名叫做Noe-Heap(非堆),目的是与Java堆区分开来
运行时常量池是方法区的一部分。Class文件中除了有类的版本,字段,方法,接口等描述信息外,还有一项信息是常量池(Constant Pool Table),用于存放编译期生成的各种字面量和符号引用,这部分将在类加载后进入方法区运行时常量池中存放。一般来说,除了保存Class文件中描述的符号引用外,还会把翻译出来的直接引用也存储在运行时常量池中。String类的intern()方法也可以放入运行时常量池中。

二:对象的创建过程

对象的创建过程:
1、虚拟机遇到new指令,首先将去检查这个指令的参数是否在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否被加载,解析和初始化过,若没有,则先进行类加载过程
2、虚拟机为新生对象分配内存,内存大小通过类加载完成后可以完全确定
内存分配方式可以分为:指针碰撞,空闲列表 两种方式
分配内存可能存在并发问题,解决方案:
1)采用同步原理,通过CAS更新保证原子性
2)把内存分配的操作按照线程划分不同的空间之中进行,即每个线程在Java堆中预先分配一小块内存,称为本地线程分配缓冲(TLAB),哪个线程分配内存,就在哪个线程的TLAB上分配,只有TLAB用完并分配新的TLAB时,才需要同步锁定。
通过 -XX: +/-UseTLAB参数类设定虚拟机是否使用此方式分配内存
3、默认初始化,虚拟机先将分配到的内存空间都初始化为零值(不包括对象头),如果使用TLAB,这步会提前到TLAB分配时进行
4、配置信息,如这个对象属于哪个类的实例,如何才能找到类的元数据信息,对象的哈希码,对象的GC分代年龄等信息,这些信息存放在对象头中
5、执行方法,对对象进行初始化

三:HotSpot对象内存布局

对象头Header 实例数据(Instatnce Data) 对其填充(Padding)
Mark Word 和 类型指针(执行它的类元数据的指针) 真正存储的对象的内容 非必然存在,仅仅是占位符

Mark Word 存放的是:对象哈希码,对象分代年龄,指向锁记录的指针,线程持有锁,偏向线程ID,偏向时间戳

类型指针(执行它的类元数据的指针),虚拟机用这个指针来确定这个对象是哪个类的实例

四:对象的访问定位

访问对象采用两种方式:
1、句柄
使用句柄访问方式,java堆中会划分出一块内存来作为句柄池,reference中存储的就是对象的句柄地址,而句柄中包含了对象实例数据和类型数据各自的具体地址信息
优点:稳定,对象被移动(垃圾收集)时,只会改变句柄中实例数据的指针,而reference本身不需要修改。
在这里插入图片描述
2、直接指针
使用直接指针方式,那么堆对象的布局中必须考虑如何放置访问类型数据的相关信息,而reference中存储的直接就是对象地址
优点:速度快
在这里插入图片描述
HotSpot虚拟机采用直接指针的方式访问对象

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

【深入理解Java虚拟机】内存管理和对象访问 的相关文章

  • Jprofile可以连接到docker中运行的JVM

    我是 JProfiler 的新手 我最近遇到了一个问题 我的Java应用程序在docker中运行 这意味着JVM在docker中运行 但我的jprofile安装在主机上 我知道 jprofiler 必须连接到 JVM 那么 jprofile
  • JVM HotSpot 上的 Java 异常计数器

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

    假设我有一个Java程序Test class 如果我使用下面的脚本 for i in 1 10 do java Test done JVM每次都会退出java Test被调用 我想要的是跑步java Test在不退出JVM的情况下多次执行
  • 如何查看JVM中JIT编译的代码?

    有什么方法可以查看 JVM 中 JIT 生成的本机代码吗 一般用法 正如其他答案所解释的 您可以使用以下 JVM 选项运行 XX UnlockDiagnosticVMOptions XX PrintAssembly 根据特定方法进行过滤 您
  • 非活动状态下的 Spring Boot 堆使用情况

    我在本地部署了一个非常简单的 spring boot 应用程序 它只有一个类 控制器 差不多就这样了 我注意到堆分配并不稳定 并且有峰值和突然下降 为什么会这样 我没有对应用程序进行过一次调用 A view from VisualVM 事实
  • HotSpot使用的Mark-Compact算法是什么?

    当阅读 Mark Compact 章节时垃圾收集手册 https rads stackoverflow com amzn click com 1420082795 提出了一系列替代方案 但其中大多数看起来很旧 理论上 例如 2 指压缩和 L
  • 什么触发了java垃圾收集器

    我对 Java 中垃圾收集的工作原理有点困惑 我知道当不再有对某个对象的实时引用时 该对象就有资格进行垃圾回收 但是如果它有对实时对象的引用怎么办 可以说我有一个节点集合 它们再次引用更多节点 List 1 gt Node a gt Nod
  • Oracle 的商业 Hotspot JVM 相对于 OpenJDK 有哪些性能优势?

    正如这个问题中所描述的 OpenJDK 与 Java HotspotVM https stackoverflow com q 44335605 1593077 Oracle 的商业 Hotspot JVM 本质上是 OpenJDK 加上一些
  • 启用JConsole远程监控是否会影响生产中的系统性能?

    Oracle Sun 说只要不在生产环境中本地运行就可以吗 http download oracle com javase 1 5 0 docs guide management jconsole html http download or
  • 在 HP Load Runner 的 VuGen 中加载 javai.dll 时出现错误

    当我尝试在 HP load runner 的 VuGen 中编译一个简单的脚本时 无法启动 JVM 并出现以下错误 Java VM Internal Error Getting Error Loading javai dll 我在用着 HP
  • 强制jvm返回本机内存[重复]

    这个问题在这里已经有答案了 我时不时地运行需要大量内存的 eclipse 任务 因此 当任务运行时 jvm 会消耗大约 2 3GB 的 RAM 这是可以的 但是一旦 jvm 占用了该内存 它就不会释放它 并且我遇到了一种情况 堆中已用内存约
  • Java 类:匿名类、嵌套类、私有类

    有人能解释一下Java中匿名类 嵌套类和私有类之间的区别吗 我想知道与每个相关的运行时成本以及每个编译器的方法 这样我就可以掌握哪个最适合用于例如性能 编译器优化的潜力 内存使用以及其他 Java 编码人员的普遍可接受性 我所说的匿名类是指
  • Bipush 在 JVM 中如何工作?

    我知道 iload 接受整数 1 到 5 但是如何使用 bipush 指令扩展到更高的数字 特定整数如何与字节码一起存储 有几种不同的指令可用于推送整数常量 最小的是iconst 指令 这些只是一个字节 因为该值是在操作码本身中编码的 ic
  • OQL 包中的所有实例

    是否有可能在OQL检索属于一个包的所有对象 或者我可以查询wildcards 正如 haridsv 建议我尝试过的 SELECT from com example and SELECT a from com example but in V
  • Java的-XX:+UseMembar参数是什么

    我在各种地方 论坛等 看到这个参数 并且常见的答案是它有助于高并发服务器 尽管如此 我还是找不到 sun 的官方文档来解释它的作用 另外 它是Java 6中添加的还是Java 5中存在的 顺便说一句 许多热点虚拟机参数的好地方是这一页 ht
  • 调整 Java 类以提高 CPU 缓存友好性

    在设计java类时 对于实现CPU缓存友好性有哪些建议 到目前为止我学到的是应该尽可能多地使用 POD 即 int 而不是整数 这样 在分配包含对象时 数据将被连续分配 例如 class Local private int data0 pr
  • Android java.exe 以非零退出值 1 结束 [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我尝试过查看类似的解决方案 但没有解决方案有效 我以前运行应用程序没有问题 但我的新应用程序突然开始给我带来问题 当我尝试运行它时总是
  • JVM GC 是否会在引用比较过程中移动对象,导致即使双方都引用同一个对象,比较也会失败?

    众所周知 GC 有时会在内存中移动对象 据我了解 只要在移动对象时 调用任何用户代码之前 更新所有引用 这应该是完全安全的 但是 我看到有人提到引用比较可能不安全 因为对象在引用比较过程中被 GC 移动 这样即使两个引用应该引用同一个对象
  • Dart/Flutter 如何编译到 Android?

    我找不到任何具体的资源 Dart 是否被编译到 JVM 或者 Google 的团队是否编译了 Dart VM 以在 JVM 上运行 然后在 JVM 内的 Dart VM 中运行 Dart 前者更有意义 并且符合 无桥 的口号 但后者似乎更符
  • 为什么java(>=7版本)不支持运行没有main方法的程序? [关闭]

    Closed 这个问题是无法重现或由拼写错误引起 help closed questions 目前不接受答案 class WithoutMain static System out println Without main class Sy

随机推荐

  • PASCAL VOC2012数据集以及制作自己的数据集

    目录 VOC2012目录结构 制作自己的数据集 标注图片软件 使用流程 软件使用 VOC2012目录结构 制作自己的数据集 标注图片软件 github开源项目 形成的是xml文件格式 使用流程 软件使用
  • 二叉搜索树的最近公共祖先Python解法

    给定一个二叉搜索树 找到该树中两个指定节点的最近公共祖先 百度百科中最近公共祖先的定义为 对于有根树 T 的两个结点 p q 最近公共祖先表示为一个结点 x 满足 x 是 p q 的祖先且 x 的深度尽可能大 一个节点也可以是它自己的祖先
  • 浙江移动容器云基于 Dragonfly 的统一文件分发平台生产实践

    2018 年 11 月 源于阿里巴巴的云原生镜像分发系统 Dragonfly 在 KubeCon 上海现场亮相 成为 CNCF 沙箱级别项目 Sandbox Level Project Dragonfly 主要解决以 Kubernetes
  • BCOS区块链性能分析工具的安装和使用perf+火焰图

    安装Perf perf的全称是Performance Event 在2 6 31版本后的Linux内核中均有集成 是Linux自带的强力性能分析工具 使用现代处理器中的特殊硬件PMU Performance Monitor Unit 性能监
  • Linux nfs挂载目录无响应解决方法

    Linux nfs挂载目录无响应解决方法 笔者在搭载linux系统的开发板上 使用nfs挂载乌班图虚拟机的目录时 在开发板上 这要涉及到挂载的目录 shell就会卡死 各种查找测试后 发现一种解决方法 卡死的原因是虚拟机的ip地址发生变化
  • Vue知识点总结(17)——作用域插槽(超级详细)

    之前分别了解了匿名插槽和具名插槽 这期我们的任务是作用域插槽 作用域插槽虽然用的不多 但是还是挺重要的 我们以一个实际需求来展示作用域插槽 因为作用域插槽用的确实不多 只能在实际需求中展示它的意义 需求 已经开发了一个待办事项列表的组件 很
  • 我彻底服了,大牛讲解信号与系统(通俗易懂)

    我彻底服了 大牛讲解信号与系统 通俗易懂 2015 10 13 21 22 36 转载 分类 电力电子技术 第一课什么是卷积卷积有什么用什么是傅利叶变换什么是拉普拉斯变换 引子 很多朋友和我一样 工科电子类专业 学了一堆信号方面的课 什么都
  • GitHub ssh-key配置

    1 安装GitHub https desktop github com 2 生成ssh key 1 打开github运行窗口 2 输入命令如下命令 这里的邮箱账号为GitHub注册时的账号 ssh keygen t rsa C xxxxxx
  • CSS&JS两种方式实现手风琴式折叠菜单

    div class accordion div class section h3 a href one 折叠栏1 a h3 div class image img src div div div class section h3 a hre
  • Maximum call stack size exceeded

    前言 小程序探究之路 报错显示 报错原因 这个意思是 超出最大调用堆栈大小 我这里是调用了腾讯的地图 然后排查各种情况 最后发现是我再注册的时候 直接用了map这个名字 但是实际上 我们调用腾讯接口用的也是map的标签 错误代码 1 调用界
  • u-boot项目管理:.config的生成

    总体简略描述 config是 scripts kconfig conf程序从根目录开始分析Kconfig文件 并结合xxx deconfig生成的配置文件 1 输入命令 make zynq defconfig 2 开始解析 Makefile
  • 需求跟踪矩阵实例_如何利用seaborn进行矩阵散点图(Pairs Plots)的绘制?

    点击上方蓝字 关注我们 如何快速创建强大的可视化探索性数据分析 这对于现在的商业社会来说 变得至关重要 今天我们就来 谈一谈如何使用 python 来进行数据的可视化 一旦你有了一个很好的被清理过的数据集 下一步就是探索性数据分析 EDA
  • Mybatis Plus实现逻辑删除

    文章目录 1 什么是逻辑删除 2 使用说明 3 如何使用Mybatis Plus实现逻辑删除 4 测试 1 什么是逻辑删除 逻辑删除是名义上的删除 就是对要要删除的数据打上一个删除标记 在逻辑上数据是被删除的 但数据本身依然存在 可通过修改
  • MHA-6 两个脚本 master_ip_failover master_ip_online_change

    master ip failover usr bin env perl use strict use warnings FATAL gt all use Getopt Long my command ssh user orig master
  • 2023天梯赛个人题解

    文章目录 L1 1 最好的文档 L1 2 什么是机器学习 L1 3 程序员买包子 L1 4 进化论 L1 5 猜帽子游戏 L1 6 剪切粘贴 L1 7 分寝室 L1 8 谁管谁叫爹 L2 1 堆宝塔 L2 2 天梯赛的赛场安排 L2 3 锦
  • vue通过el-upload组件上传文件到服务器使用总结

    vue通过el upload组件上传文件到服务器使用总结 1 业务需求 vue项目需要通过elementUI的el upload组件上传文件 但是一般情况下请求接口是需要携带token值的 如果不携带则上传不成功 而el upload是通过
  • python为什么叫爬虫?Python和爬虫有什么关系?

    提到Python有同学自然就想到爬虫 但实际上Python和爬虫并不是一个概念的东西哦 下面小千就来给大家介绍一下 爬虫 爬虫又称网络爬虫 又称为网页蜘蛛 网络机器人 在FOAF社区中间 经常的称为网页追逐者 是一种按照一定的规则 自动地抓
  • 【单目标优化算法】沙猫群优化算法(Matlab代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 参考文献 4 Matlab代码实现 1 概述 本研究提出了一种新的元启发式算法 称为沙猫
  • mysql第三次上机

    Mysql第三次上机 上机3 1 基于第一次上机创建的银行数据库 创建一个函数 为所有存款账户增加1 的利息 2 创建一个新表branch total 用于存储各个支行的存款总额 表中有branch name和total balance两个
  • 【深入理解Java虚拟机】内存管理和对象访问

    一 JVM内存区域划分 1 程序计数器 线程私有 类似于eclipse中断点程序 行号指示器 记录了程序下一步需要执行的字节码指令 分支 循环等分支 线程私有 每个线程有一个程序计数器 程序计数器是为了多线程情况下 线程执行切换后 处理器回