翻译人员: 铁锚

翻译日期: 2013年11月8日

原文链接:  What do Java objects look like in memory during run-time?



我们知道,函数每次被调用时,在内存中都有自己的活动记录(activation record),称为栈空间(stack). Java 的方法在调用时在 JVM 栈中为其分配一个栈帧(Java栈空间的一个片段),可以称之为方法栈. 原则上,所有对象都在堆空间(Heap)中分配.



java对象在内存中是怎样分配的呢? 一旦对象在堆中分配了空间,那本质上就是一系列的字节. 那么如何找到对象中某个特定的属性域呢? 编译器通过一个内部表来保存每个域的偏移量.



下图是 Base 类的一个对象内存分布图,Base(基类)没有定义任何方法,关于方法在内存中的分布请看接下来的内容.

图1

如果还有另一个派生类 "Derived" 继承了基类"Base".那么内存分布将如下图所示:

图2

子类对象和父类对象拥有同样的内存分布,当然,子类对象需要更多的空间来存放新的属性域.

这种分配方式的好处在于 Base类型的指针 如果指向了子类Derived的对象, 依然在开头的地方"看见"Base对象.

因此, 子类对象(Derived)采用 父类引用(Base) 来进行的操作 保证是安全的,因此在运行时不需要动态地检查 Base 引用的实际类型.

用样的道理,方法也可以放到object空间的开始处,如下图所示.

图3

然而这种实现方式是没有效率的.假若一个类有很多方法(例如20个),那么每个对象就要持有20个指针,相应的,每个对象都需要20个指针的内存空间,这会导致创建对象变慢,所占空间更大。

优化手段是创建一个 虚拟函数表(vtable,虚表),虚表是一个指向特定类的成员函数的指针数组. 如下图所示:

图4

* 以上是我对斯坦福大学编译器讲座所做的笔记,该讲座非常生动有趣。

参考文献:

1. Stanford Compilers
Lectures


2.  JVM

相关文章:

  1. What
    does a Java array look like in memory?
  2. Top
    5 Questions about C/C++ Pointers
  3. 简述Java内存泄露
  4. An
    example of C++ dot vs. arrow usage

Java 对象在堆中的内存结构的更多相关文章

  1. 重磅硬核 | 一文聊透对象在 JVM 中的内存布局,以及内存对齐和压缩指针的原理及应用

    欢迎关注公众号:bin的技术小屋 大家好,我是bin,又到了每周我们见面的时刻了,我的公众号在1月10号那天发布了第一篇文章<从内核角度看IO模型的演变>,在这篇文章中我们通过图解的方式以 ...

  2. Java中JVM内存结构

    Java中JVM内存结构 线程共享区 方法区: 又名静态成员区域,包含整个程序的 class.static 成员等,类本身的字节码是静态的:它会被所有的线程共享和是全区级别的: 属于共享内存区域,存储 ...

  3. 受检查异常要求try catch,new对象时,就会在堆中创建内存空间,创建的空间包括各个成员变量类型所占用的内存空间

    ,new对象时,就会在堆中创建内存空间,创建的空间包括各个成员变量类型所占用的内存空间

  4. windows进程中的内存结构[转载]

    在阅读本文之前,如果你连堆栈是什么多不知道的话,请先阅读文章后面的基础知识. 接触过编程的人都知道,高级语言都能通过变量名来访问内存中的数据.那么这些变量在内存中是如何存放的呢?程序又是如何使用这些变 ...

  5. windows进程中的内存结构(好多API,而且VC最聪明)

    在阅读本文之前,如果你连堆栈是什么多不知道的话,请先阅读文章后面的基础知识.   接触过编程的人都知道,高级语言都能通过变量名来访问内存中的数据.那么这些变量在内存中是如何存放的呢?程序又是如何使用这 ...

  6. windows进程中的内存结构(缓冲溢出原理)

    接触过编程的人都知道,高级语言都能通过变量名来访问内存中的数据.那么这些变量在内存中是如何存放的呢?程序又是如何使用这些变量的呢?下面就会对此进行深入的讨论.下文中的C语言代码如没有特别声明,默认都使 ...

  7. 一个Java对象到底占用多大内存?

    最近在读<深入理解Java虚拟机>,对Java对象的内存布局有了进一步的认识,于是脑子里自然而然就有一个很普通的问题,就是一个Java对象到底占用多大内存? 在网上搜到了一篇博客讲的非常好 ...

  8. 一个Java对象到底占用多大内存

    在网上搜到了一篇博客讲的非常好,里面提供的这个类也非常实用: import java.lang.instrument.Instrumentation; import java.lang.reflect ...

  9. Java对象在JVM中的生命周期

          当你通过new语句创建一个java对象时,JVM就会为这个对象分配一块内存空间,只要这个对象被引用变量引用了,那么这个对象就会一直驻留在内存中,否则,它就会结束生命周期,JVM会在合适的时 ...

随机推荐

  1. 06 Nexus仓储/基础设施 - DevOps之路

    06 Nexus仓储/基础设施 - DevOps之路 文章Github地址,欢迎start:https://github.com/li-keli/DevOps-WiKi Nexus仓储官网简介: Th ...

  2. 关于使用Git的几点小技巧

    告诉git忽略对已经纳入版本管理的文件a的修改,git会一直忽略此文件直到重新告诉git可以再次跟踪此文件: git update-index --assume-unchanged a 告诉git恢复 ...

  3. Linux完全卸载Oracle的操作步骤

    卸载步骤如下:1.运行$ORACLE_HOME/bin/localconfig delete2.rm -rf $ORACLE_BASE/*3.rm -f /etc/oraInst.loc etc/or ...

  4. LinkedList源码和并发问题分析

    1.LinkedList源码分析 LinkedList的是基于链表实现的java集合类,通过index插入到指定位置的时候使用LinkedList效率要比ArrayList高,以下源码分析是基于JDK ...

  5. Python中的数据类型

    计算机顾名思义就是可以做数学计算的机器,因此,计算机程序理所当然地可以处理各种数值.但是,计算机能处理的远不止数值,还可以处理文本.图形.音频.视频.网页等各种各样的数据,不同的数据,需要定义不同的数 ...

  6. 初步配置阿里云ECS服务器

    阿里云服务器配置记录01 购买阿里云学生服务器9.9元每月 创建ubuntu64位实例系统,注意必须添加安全组设置才可远程登入(设置课访问端口及IP范围 putty 软件在windows10下远程登入 ...

  7. Linux shell爬虫实现树洞网自动回复Robot

    奇怪的赞数 人生在世,不如意事十之八九,可与言者无二三人.幸好我们生在互联网时代,现实中找不到可以倾诉的人还可以在网络上寻找发情绪宣泄口,树洞这类产品就是提供一个让人在网络上匿名倾诉的平台. 我是偶然 ...

  8. python3.6 使用 pymysql 连接 Mysql 数据库及 简单的增删改查操作

    1.通过 pip 安装 pymysql 进入 cmd  输入  pip install pymysql   回车等待安装完成: 安装完成后出现如图相关信息,表示安装成功. 2.测试连接 import ...

  9. 计算机网络之局域网&以太网

    局域网的拓扑结构 局域网最主要的特点是:网络为一个单位所拥有,且地理范围和站点数目均有限. 局域网具有广播功能,从一个站点可很方便地访问全网,局域网上的主机可共享连接在局域网上的各种硬件和软件资源. ...

  10. cassandra 并发技术介绍

    摘要 本文主要介绍cassandra线程技术,cassandra的实现是基于java的,所以线程技术使用的也是jdk包提供的线程类.cassandra是分布式数据库,整个并发架构是基于阶段事件驱动架构 ...