Java对象:在内存中的真面目

在Java中,通过new关键字创建一个Java类的实例对象时,该对象会通过碰撞指针方式存储在内存的堆中,并被分配一个内存地址。在Java虚拟机中,一个Java对象由对象头(Object Header)、实例数据(Instance Data)和对齐填充(Padding)三部分构成。

对象头

对象头由两个字(计算机术语,表示计算机处理数据的最小单位)组成。如果对象是一个Java数组,对象头中还必须包含一部分用于记录数组长度的数据,因为虽然Java虚拟机可以通过Java对象的元数据信息确定Java对象的大小,但无法从数组的元数据中确定数组的大小。

对象头的两个字分别是Mark Word和Klass Pointer。

1)Mark Word:即标记字段,用于存储对象自身的运行时数据,如哈希码(HashCode)、垃圾回收分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等。

2)Klass Pointer:即类型指针,是对象指向它的类元数据的指针,Java虚拟机通过这个指针来确定这个对象是哪个Java类的实例。

实例数据

实例数据部分存储对象的属性字段信息。如果对象没有属性字段,那么这部分就不会有数据。字段类型的不同会占用不同的字节,例如,boolean类型占1个字节,int类型占4个字节等。

对齐填充

对齐填充是为了满足Java虚拟机堆中对象起始地址需要对齐至8的倍数的要求。如果一个对象未使用到8N个字节,则需要进行填充,以补齐对象头和实例数据占用内存后的剩余空间。

字段内存对齐的目的之一是确保字段只出现在同一处理器的缓存行中。如果字段未对齐,可能会出现跨缓存行的字段,即该字段的读取可能需要替换两个缓存行,而该字段的存储也可能同时污染两个缓存行,这对程序执行效率都是不利的。实际上,对齐填充的最终目标是为了实现计算机的高效寻址。

压缩指针

在64位Java虚拟机中,对象头部的Mark Word和Klass Pointer,分别占据64位,因此每个Java对象的内存额外开销就是16字节。以Integer类为例,它仅有一个int类型的私有字段,占用4字节,因此,每个Integer对象的内存开销至少增加400%。这也是Java引入基本数据类型(Primitive Data Type)的原因之一。

在64位系统中,普通的对象引用通常需要64位(8字节)的空间。然而,对于许多应用程序,这种大尺寸的引用是不必要的,因为它们的堆内存使用量远小于64位地址空间的上限(即18亿GB)。因此,64位Java虚拟机引入了压缩指针(Compressed Pointer)技术,将Java对象指针压缩为32位。这样,对象头部中的Klass Pointer也被压缩为32位,从而将对象头部的大小从16字节减小到12字节。

工作原理

Java虚拟机假设所有对象的大小都是8字节的倍数(不足将对齐填充),因此对象的实际地址可以表示为基地址加上一个偏移量,而这个偏移量是8的倍数。因此,Java虚拟机只需要存储这个偏移量,而不是完整的64位地址。由于偏移量是8的倍数,所以它的最后三位总是0,Java虚拟机可以将这个偏移量右移三位,从而将其压缩到32位的空间。

下面是8和它的倍数对应的二进制关系。

8 = 1000
16 = 10000
24 = 11000
32 = 100000
40 = 101000
48 = 110000
56 = 111000
64 = 1000000
72 = 1001000

可以看到,在二进制下,8和它的倍数的后三位都是0。因为后三位都是0,所以可以在拿到地址后舍弃后三位,读取的时候加上后三位。这个过程可以用以下的伪代码表示。

int offset = getObjectOffset(); // 获取对象的32位偏移量

offset = offset << 3; // 将偏移量左移三位

long address = HEAP_BASE + offset; // HEAP_BASE是堆基地址,加上偏移量就可以得到对象的实际内存地址。

需要注意的是,压缩指针技术只适用于堆内存大小小于32GB的情况。如果堆内存大小超过32GB,那么32位的偏移量将不足以表示所有可能的对象位置,因此必须使用完整的64位引用。

未完待续

很高兴与你相遇!如果你喜欢本文内容,记得关注哦

压缩指针:64位系统下,Java虚拟机是如何“偷”回4字节内存的?的更多相关文章

  1. linux CentOs 7.4 64位 系统下 nuxt部署 、nginx 安装、node环境及软连接,pm2软连接

    一.nginx安装 1.安装依赖包 //一键安装上面四个依赖 yum -y install gcc zlib zlib-devel pcre-devel openssl openssl-devel 2 ...

  2. 64位系统下注册32位dll文件

    64位系统下注册32位dll文件 在64位系统里注册32位软件所需的一些dll会提示不兼容,大概因为32 位进程不能加载64位Dll,64位进程也不可以加载32的导致. 若要支持的32 位和64 位C ...

  3. PL/SQL Developer 在windows7 64位系统下连Oaracle11g64位系统的解决经验

    PL/SQL Developer 在windows7 64位系统下连Oaracle11g64位系统的解决经验 一.问题现象及解决方法 现象: 1.PL/SQL 无法登录64位数据库 2.在PL/SQL ...

  4. 64位系统下System32文件系统重定向

    前言 因为一次偶然的机会,需要访问系统目录“C:/Windows/System32“文件夹下的内容,使用的测试机器上预装了win7 64系统.在程序运行中竟然发生了该文件路径不存在的问题!!通过查看网 ...

  5. win7 64位系统下安装autoitlibrary库遇到问题解决

    转载来自http://blog.sina.com.cn/s/blog_53f023270101skyq.html 今天需要在win7 64位系统下安装autoitlibrary库,起初安装好了robo ...

  6. (转)Win7 64位系统下 Retional rose 2003 安装及破解

    网上关于Retional rose 2003安装和破解的文章比较多,这里,我结合自己的亲身体验,和大家分享一下win7 旗舰版 64位系统下Retional rose 2003(下面简称rose200 ...

  7. 64位系统下注册32位dll、ax文件

    64位系统下注册32位dll.ax文件. 换了64位系统遇到的新问题,目前常用的影音处理软件多数为32位. 注册这些32的滤镜会提示不兼容,大概因为32 位进程不能加载64位Dll,64位进程也不可以 ...

  8. Win7 64位系统下 Retional rose 2003 安装及破解

    网上关于Retional rose 2003安装和破解的文章比较多,这里,我结合自己的亲身体验,和大家分享一下win7 旗舰版 64位系统下Retional rose 2003(下面简称rose200 ...

  9. 64位系统下,一个32位的程序究竟可以申请到多少内存,4GB还是更多?(一)

    前言: cpu的位是指一次性可处理的数据量是多少,1字节=8位,32位处理器可以一次性处理4个字节的数据量,依次类推.32位操作系统针对的32位的CPU设计.64位操作系统针对的64位的CPU设计.操 ...

  10. C#在 64位系统下出现 “未能加载文件或程序集”错误

    64位系统下,Build的时候,如果选择Any CPU,默认会按照64位进行编译,便无法加载某些旧的dll,这些dll可能是特定到X86 CPU的. 所以,把编译选项中改为 X86CPU,就可以运行了 ...

随机推荐

  1. 免费的个人网站托管-InfinityFree

    前情 对于前端开发来说,拥有一个自己的个人网站是一种执着也是一种排面,但是大部分前端也都对服务端这一块的东西都停留在了解阶段,但是如果正儿八经的上线一个网站或多或少需要懂一些服务端知识,需要购买服务器 ...

  2. Negigent Norbert Gym - 102680E

    https://vjudge.net/problem/Gym-102680E/origin https://vjudge.net/contest/396206#problem/E Naughty Ne ...

  3. JavaScript知识-函数基础知识、匿名函数、闭包函数、箭头函数、js内置对象和方法

    目录 JavaScript函数 1.函数的语法格式 2.无参函数 3.有参函数 4.关键字arguments 5.函数返回值 关键字return 6.匿名函数(没有函数名) 7.箭头函数 8.函数的全 ...

  4. Dijkstra算法理解-无人机路径规划

    1.理解 Dijkstra算法是路径规划算法中非常经典的一种算法,在很多地方都会用到,特别是在机器人的路径规划中,基本学习机器人运动相关的都会接触到该算法. Dijkstra算法本身的原理是基于贪心思 ...

  5. LLaMA-Factory与DeepSeek-R1-7B:微调垂直行业大模型(LORA微调

    https://blog.csdn.net/2401_85325726/article/details/147037214 一.大模型微调部署框架为了让开发者拥有一个简便.高效的工具,以便在现有的开源 ...

  6. 企业抢着要的AI方案:DeepSeek-R1微调实战,3天构建行业内容生成器

    https://juejin.cn/post/7479399201999486976 1. 前言 在如今快速发展的AI技术领域,越来越多的企业正在将AI应用于各个场景.然而,尽管大模型(如GPT.De ...

  7. Windows下Minio介绍、安装及使用、密码修改

    最近在使用minio做图片.文件存储,在使用过程中遇到一些问题,总结记录下来.这里不对minio做过多介绍,具体资料自行查找. https://docs.min.io/docs/dotnet-clie ...

  8. 信而泰推出POE交换机一站式自动化测试方案

    方案背景 传统POE交换机测试工序主要有扫条码,接网线,POE供电测试,流量测试,LED测试,信息核对等,基本都依赖于手工操作,效率偏低,并且LED测试,POE供电测试依赖人工判断是否良品,容易误测. ...

  9. .NET周刊【8月第3期 2025-08-17】

    国内文章 精选 5 款 .NET 开源.功能强大的工作流系统,告别重复造轮子! https://www.cnblogs.com/Can-daydayup/p/19038600 本文推荐了5款适用于.N ...

  10. 排查慢SQL思路

    引言 慢SQL是指执行时间较长的SQL语句,可能会影响系统的性能和响应时间.为了解决慢SQL问题,我们需要进行排查和优化.这里将介绍一些常用的排査慢SQL的思路和方法. 1.监控数据库性能 我们需要监 ...