翻译自这一篇文章

我们知道函数在内存中实现为一个活动记录的栈。我们也知道Java方法在JVM栈区中实现为一个帧栈而Java对象是在堆区进行分配的。

Java对象在堆内存中是怎样的呢?一旦对象保存在内存中,就只是字节序列。

那么我们如何知道去哪里查找某个字段?在编译器内部保留一个内部表,来记录每个字段的偏移量。

下面的例子,是关于类“Base”(B)的对象布局。这个类中没有任何方法,类方法在内存中的存储方法会在下一节说到。

如果我们有一个类“Derived”(D)继承了这个“Base”类。那么内存分布就如下

子对象有着与父对象相同的内存分布,只不过它还需要多一些的空间来存放新增的成员。这种布局方式的好处在于,一个B类型的指针指向D对象时,仍然可以在内存区域的开始部分找到B对象。因此,通过B引用来对D对象进行操作都保证是安全的,从而也就不必动态地检查B指向的是什么。

按照同样的逻辑,方法可以被放在对象的开头处。

不过,这个方法效率不高。如果一个类中有很多方法(比如说,M个),那么每个对象都必须有O(M)的指针集。此外,每一个对象都需要有可容纳O(M)指针的空间。这些要求使得创建对象更慢而对象占用更大。

最佳是方法就是去创建一个虚函数表,这是一个指针数组,其中的指针指向某个类的具体成员函数实现。为每一个类创建一个虚函数表的实例,并在每个对象中保存一个指向虚函数表的指针。

这个就是最优化的方法。

【Java】运行时Java对象在内存中是如何存储的?的更多相关文章

  1. java对象在内存中的结构

    在HotspotJVM中,32位机器下,Integer对象的大小是int的几倍? 我们都知道在java语言规范已经规定了int的大小是4个字节,那么Integer对象的大小是多少呢?要知道一个对象的大 ...

  2. java对象在内存中的结构(HotSpot虚拟机)

    一.对象的内存布局 HotSpot虚拟机中,对象在内存中存储的布局可以分为三块区域:对象头(Header).实例数据(Instance Data)和对齐填充(Padding). 从上面的这张图里面可以 ...

  3. java对象在内存中的分配

    java对象在内存中的分配 http://blog.csdn.net/qq_30753945/article/details/54974899

  4. Java中对象在内存中的大小、分配等问题

    Java创建一个对象的过程 是否对象指向的类已经加载到内存了 如果没有加载,就要经过load.linking(verification.preparation.resolution).initiali ...

  5. Java基础-IO流对象之内存操作流(ByteArrayOutputStream与ByteArrayInputStream)

    Java基础-IO流对象之内存操作流(ByteArrayOutputStream与ByteArrayInputStream) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.内存 ...

  6. JVM中,对象在内存中的布局

    在hotSpot虚拟机中,对象在内存中的布局可以分成对象头.实例数据.对齐填充三部分. 对象头:主要包括: 1.对象自身的运行行元数据,比如哈希码.GC分代年龄.锁状态标志等,这部分长度在32位虚拟机 ...

  7. JVM运行时数据区及对象在内存中初始化的过程

    JVM运行时数据区 Java虚拟机所管理的内存区域,也称为运行时数据区,分为以下几个运行时数据区,如图所示 程序计数器:当前程序所执行字节码的行号指示器 程序计数器(Program Counter R ...

  8. JS面向对象(1) -- 简介,入门,系统常用类,自定义类,constructor,typeof,instanceof,对象在内存中的表现形式

    相关链接: JS面向对象(1) -- 简介,入门,系统常用类,自定义类,constructor,typeof,instanceof,对象在内存中的表现形式 JS面向对象(2) -- this的使用,对 ...

  9. C# CLR via 对象内存中堆的存储【类型对象指针、同步块索引】

    最近在看书,看到了对象在内存中的存储方式. 讲到了对象存储在内存堆中,分配的空间除了类型对象的成员所需的内存量,还有额外的成员(类型对象指针. 同步块索引 ),看到这个我就有点不懂了,不知道类型对象指 ...

随机推荐

  1. 使用python -m pip install 和 pip install 安装包有什么区别?

    如果去看源码的话,你会发现 pip 作为执行文件的入口点是 pip._internal.main. 另一方面,pip 作为模块运行时入口是 _main.py,而该模块也只是调用 pip.interna ...

  2. Java基础之(六):变量、运算符与JavaDoc

    变量.常量 一.变量的命名规范 首字母只能以字母(A-Z或者a-z)或者美元符($)或者下划线(_)开头,不能以数字开头,首字母之后只能跟字母(AZ或者az)或者数字,不能跟美元符或者下划线 源码 p ...

  3. 在 ASP.NET Core Web API中使用 Polly 构建弹性容错的微服务

    在 ASP.NET Core Web API中使用 Polly 构建弹性容错的微服务 https://procodeguide.com/programming/polly-in-aspnet-core ...

  4. LeetCode:BFS/DFS

    BFS/DFS 在树专题和回溯算法中其实已经涉及到了BFS和DFS算法,这里单独提出再进一步学习一下 BFS 广度优先遍历 Breadth-First-Search 这部分的内容也主要是学习了labu ...

  5. GitHub Universe 2021|MS Reactor 邀你共聚年度盛会

    GitHub Universe 2021 将于2021年10月27-28日(PDT)在线直播,MS Reactor 将与 CSDN 合作进行转播,与你一同观看这场全球开发者盛会. 关于 GitHub ...

  6. FastAPI 学习之路(五十五)操作Redis

    之前我们分享了操作关系型数据库,具体文章, FastAPI 学习之路(三十二)创建数据库 FastAPI 学习之路(三十三)操作数据库 FastAPI 学习之路(三十四)数据库多表操作 这次我们分享的 ...

  7. [CPP] 类的内存布局

    本文可以解决下面 3 个问题: 以不同方式继承之后,类的成员变量是如何分布的? 虚函数表及虚函数表指针,在可执行文件中的位置? 单一继承.多继承.虚拟继承之后,类的虚函数表的内容是如何变化的? 在这里 ...

  8. 同人逼死官方系列!基于sddc 协议的SDK框架 sddc_sdk_lib 解析

    基于sddc 协议的SDK框架 sddc_sdk_lib 解析 之前在移植 libsddc 库的时候感觉官方 demo 太低效了( ̄. ̄),复制粘贴代码好累,而且写出一个BUG,其他复制的代码整个就裂 ...

  9. threading python2 和python3

    from __future__ import division from __future__ import print_function import threading balance = 0 d ...

  10. 加法运算替代 牛客网 程序员面试金典 C++ Python

    加法运算替代 牛客网 程序员面试金典 题目描述 请编写一个方法,实现整数的乘法.减法和除法运算(这里的除指整除).只允许使用加号. 给定两个正整数int a,int b,同时给定一个int type代 ...