`

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(基类)没有定义任何方法,关于方法在内存中的分布请看接下来的内容.

图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 usageYarpp
分享到:
评论

相关推荐

    java对象在内存中的结构

    Java对象在内存中的结构及其生命周期是Java编程中基础且关键的概念。Java的内存管理主要涉及栈(Stack)和堆(Heap)两个区域,对于理解程序的性能和内存使用至关重要。 首先,栈主要用于存储基本数据类型(如int, ...

    java 对象在内存中的结构

    实例化对象时,会在堆内存中为类的成员变量分配内存,并将其初始化为各数据类型的默认值,然后进行显式初始化,最后调用构造方法,为成员变量赋值。 在 Java 中,对象的内存模型可以分为三个部分:基本数据类型的...

    探讨Java的对象是怎么在内存中产生的?

    本文将详细探讨Java对象在JVM中的创建过程以及其内存布局,帮助读者更深入地理解Java对象是如何在内存中产生的。 #### 二、对象的创建 Java对象是由类实例化的结果,当我们使用`new`关键字创建一个对象时,实际上...

    Java中堆内存与栈内存分配浅析

    - 对象实例:所有Java对象都存储于堆内存中。 - 数组:无论是基本数据类型的数组还是对象类型的数组,其元素都位于堆内存中。 - 复杂数据结构:例如链表、树等。 ##### 2. 栈内存 栈内存主要用于存储基本数据...

    Java对象在内存中的结构.doc

    Java对象在内存中的结构主要涉及两个关键区域:栈(Stack)和堆(Heap),这是Java内存管理的基础。栈主要用于存储基本类型和对象引用,而堆则用于存储对象实例。 1. 栈内存: 栈内存是Java运行时环境中的一个重要...

    Java中堆内存和栈内存详解

    - **对象引用**:为了访问堆内存中的对象,可以在栈内存中创建一个引用变量,该变量的值为对象在堆内存中的地址。 - **垃圾回收**:Java虚拟机(JVM)会自动管理堆内存,通过垃圾回收机制(Garbage Collection, GC)...

    Java内存结构

    Java内存结构是Java编程语言中的一种基本概念,它决定了Java程序的运行机制。Java内存结构可以分为六个部分:寄存器、栈、堆、静态存储、常量存储和非RAM存储。其中,堆和栈是Java程序运行时最重要的两个存储区域。 ...

    java 对象 内存 大小

    当我们谈论“Java对象内存大小”时,我们通常指的是一个Java对象在内存中占据的空间,包括对象头、实例字段以及可能的对齐填充。这个知识点对于开发高效缓存系统尤其重要,因为缓存需要精确管理内存来最大化存储效率...

    Java对象内存布局 - 小分析

    对象在堆中存储时,通常包含以下几部分: 1. **对象头(Object Header)**:包括标记字段(Mark Word)和类型指针。标记字段记录对象的哈希码、锁状态、GC标记等信息,类型指针指向对象的类元数据,以便于虚拟机...

    JAVA中的面向对象与内存解析

    当我们使用`new`关键字创建对象时,首先在堆内存中为对象分配空间,然后调用构造函数初始化对象的属性。对象的引用会被存储在栈内存中,供后续使用。理解这个过程有助于优化代码性能,避免过度创建对象导致的内存...

    JVM内存结构、Java内存模型、Java对象模型1

    Java虚拟机(JVM)内存结构是Java程序运行的基础,它将内存划分为若干个不同的数据区域,包括...而Java对象模型则决定了对象在内存中的布局和访问方式。每个主题都值得深入研究,以便更好地理解和调试Java程序的行为。

    Java内存结构.pdf

    1. JVM尝试在Eden中为Java对象分配内存。 2. 如果Eden空间足够,则直接分配;否则触发GC。 3. 如果GC后Eden空间仍然不足,则尝试将部分Eden中的存活对象转移到Survivor区。 4. 如果Survivor区空间也不足,则尝试将...

    JAVA对象所占内存大小计算例子

    首先,我们需要理解Java对象内存占用的基本原理。每个Java对象都由三部分组成:对象头(Object Header)、实例数据(Instance Data)和对齐填充(Padding)。对象头包含对象引用和类型信息,实例数据是对象实际存储...

    Java内存使用系列一Java对象的内存占用Java开发J

    首先,我们来谈谈Java对象的内存结构。每个Java对象都由三部分组成:对象头、实例数据和对齐填充。对象头包含指向类元数据的指针以及用于同步和垃圾回收的标记。实例数据是对象实际存储的字段值。对齐填充可能存在于...

    java内存对象分配过程研究

    1. **内存分配**:当使用`new`关键字创建对象时,JVM会在堆上为新对象分配一块内存空间,并返回一个指向这块内存空间的引用。例如: ``` new Color(100, 100, 120); ``` 这里`new`运算符负责为对象分配内存空间...

    java中的栈(深层了解java虚拟机对对象的内存分布)

    另一方面,所有引用类型,如包装类(Integer、String、Double等),以及自定义的类对象,都存储在堆中。这是因为它们的大小和生命周期可能在程序运行过程中发生变化,堆的动态内存管理特性正好满足这一需求。 #### 字...

    Java堆内存管理:深入解析与代码实践

    Java堆内存是Java虚拟机(JVM)中最大的一块内存区域,主要用于存储对象实例和数组。理解堆内存的划分、分配机制和垃圾回收过程对于Java开发者来说至关重要,因为这些知识可以帮助他们优化应用程序的性能,避免内存...

Global site tag (gtag.js) - Google Analytics