Java 对象在堆中的内存结构
翻译人员: 铁锚
翻译日期: 2013年11月8日
原文链接: What do Java objects look like in memory during run-time?
我们知道,函数每次被调用时,在内存中都有自己的活动记录(activation record),称为栈空间(stack). Java 的方法在调用时在 JVM 栈中为其分配一个栈帧(Java栈空间的一个片段),可以称之为方法栈. 原则上,所有对象都在堆空间(Heap)中分配.
java对象在内存中是怎样分配的呢? 一旦对象在堆中分配了空间,那本质上就是一系列的字节. 那么如何找到对象中某个特定的属性域呢? 编译器通过一个内部表来保存每个域的偏移量.
下图是 Base 类的一个对象内存分布图,Base(基类)没有定义任何方法,关于方法在内存中的分布请看接下来的内容.
如果还有另一个派生类 "Derived" 继承了基类"Base".那么内存分布将如下图所示:
子类对象和父类对象拥有同样的内存分布,当然,子类对象需要更多的空间来存放新的属性域.
这种分配方式的好处在于 Base类型的指针 如果指向了子类Derived的对象, 依然在开头的地方"看见"Base对象.
因此, 子类对象(Derived)采用 父类引用(Base) 来进行的操作 保证是安全的,因此在运行时不需要动态地检查 Base 引用的实际类型.
用样的道理,方法也可以放到object空间的开始处,如下图所示.
然而这种实现方式是没有效率的.假若一个类有很多方法(例如20个),那么每个对象就要持有20个指针,相应的,每个对象都需要20个指针的内存空间,这会导致创建对象变慢,所占空间更大。
优化手段是创建一个 虚拟函数表(vtable,虚表),虚表是一个指向特定类的成员函数的指针数组. 如下图所示:
* 以上是我对斯坦福大学编译器讲座所做的笔记,该讲座非常生动有趣。
参考文献:
1. Stanford Compilers
Lectures
2. JVM
相关文章:
- What
does a Java array look like in memory? - Top
5 Questions about C/C++ Pointers - 简述Java内存泄露
- An
example of C++ dot vs. arrow usage
Java 对象在堆中的内存结构的更多相关文章
- 重磅硬核 | 一文聊透对象在 JVM 中的内存布局,以及内存对齐和压缩指针的原理及应用
欢迎关注公众号:bin的技术小屋 大家好,我是bin,又到了每周我们见面的时刻了,我的公众号在1月10号那天发布了第一篇文章<从内核角度看IO模型的演变>,在这篇文章中我们通过图解的方式以 ...
- Java中JVM内存结构
Java中JVM内存结构 线程共享区 方法区: 又名静态成员区域,包含整个程序的 class.static 成员等,类本身的字节码是静态的:它会被所有的线程共享和是全区级别的: 属于共享内存区域,存储 ...
- 受检查异常要求try catch,new对象时,就会在堆中创建内存空间,创建的空间包括各个成员变量类型所占用的内存空间
,new对象时,就会在堆中创建内存空间,创建的空间包括各个成员变量类型所占用的内存空间
- windows进程中的内存结构[转载]
在阅读本文之前,如果你连堆栈是什么多不知道的话,请先阅读文章后面的基础知识. 接触过编程的人都知道,高级语言都能通过变量名来访问内存中的数据.那么这些变量在内存中是如何存放的呢?程序又是如何使用这些变 ...
- windows进程中的内存结构(好多API,而且VC最聪明)
在阅读本文之前,如果你连堆栈是什么多不知道的话,请先阅读文章后面的基础知识. 接触过编程的人都知道,高级语言都能通过变量名来访问内存中的数据.那么这些变量在内存中是如何存放的呢?程序又是如何使用这 ...
- windows进程中的内存结构(缓冲溢出原理)
接触过编程的人都知道,高级语言都能通过变量名来访问内存中的数据.那么这些变量在内存中是如何存放的呢?程序又是如何使用这些变量的呢?下面就会对此进行深入的讨论.下文中的C语言代码如没有特别声明,默认都使 ...
- 一个Java对象到底占用多大内存?
最近在读<深入理解Java虚拟机>,对Java对象的内存布局有了进一步的认识,于是脑子里自然而然就有一个很普通的问题,就是一个Java对象到底占用多大内存? 在网上搜到了一篇博客讲的非常好 ...
- 一个Java对象到底占用多大内存
在网上搜到了一篇博客讲的非常好,里面提供的这个类也非常实用: import java.lang.instrument.Instrumentation; import java.lang.reflect ...
- Java对象在JVM中的生命周期
当你通过new语句创建一个java对象时,JVM就会为这个对象分配一块内存空间,只要这个对象被引用变量引用了,那么这个对象就会一直驻留在内存中,否则,它就会结束生命周期,JVM会在合适的时 ...
随机推荐
- JSP运行过程 JSP脚本 静态动态包含 jsp指令 jsp内置对象jsp四大作用域 jsp动作元素 EL表达式 JSTL 设计模式 JSP开发模式 EL内置对象
Day38 JSP JSP的运行过程具体如下: (1)客户端发出请求,请求访问JSP文件. (2)JSP容器先将JSP文件转换成一个Java源文件(Java Servlet源程序),在转换过程中,如果 ...
- win8以上系统查看iis网站进程内存占用情况
由于win8以上系统在任务管理器中已经屏蔽了具体的IIS网站的进程,在进程以及详细中无法区分是哪个站点了,所以我们需要先知道各站点对应的进程pid,然后再到任务管理器中根据具体的pid查看资源占用情况 ...
- PHP XML SimpleXML
PHP 可以基于 SimpleXML 生成和解析 xml 的方法,通过本节的实例,你将了解 PHP 是如何使用 SimpleXML 生成及解析 xml 格式数据的. PHP SimpleXML 处理最 ...
- Docker 联合文件系统
联合文件系统(UnionFS)是一种分层.轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several dir ...
- matplotlib画散点图,并在散点处打上相应标签
运行环境: py3.6 matplotlib 2.1.2 x = [2,4,6,7,8,5,4,3] y = [3,6,5,8,4,3,2,4] txt = ['我','今','晚','上','吃', ...
- 初识mybatis(二)
上篇博客我们介绍通过Java代码来创建mybatis的配置文件,港真,这种方式看起来有意思实际在开发中用的并不多,mybatis的配置还是以xml配置为主,本文我们就来看看如何通过xml文件来配置my ...
- Github Atom开源文本代码编辑器- 由 Github 打造的下一代编程开发利器
个人理解:Github 热度超凡的一个项目Atom,electron是整个atom的核心,对于electron可以理解成 electron =io.js + Chromium 通过 Electr ...
- 自定义View实现五子棋游戏
成功的路上一点也不拥挤,因为坚持的人太少了. ---简书上看到的一句话 未来请假三天顺带加上十一回家结婚,不得不说真是太坑了,去年婚假还有10天,今年一下子缩水到了3天,只能赶着十一办事了. 最近还在 ...
- Android自定义View(LineBreakLayout-自动换行的标签容器)
最近一段时间比较忙,都没有时间更新博客,今天公司的事情忙完得空,继续为我的自定义控件系列博客添砖加瓦.本篇博客讲解的是标签自动换行的布局容器,正好前一阵子有个项目中需要,想了想没什么难度就自己弄了 ...
- Spark核心类:弹性分布式数据集RDD及其转换和操作pyspark.RDD
http://blog.csdn.net/pipisorry/article/details/53257188 弹性分布式数据集RDD(Resilient Distributed Dataset) 术 ...