精华内容
下载资源
问答
  • 对于HotSpot虚拟机来说,Java类的实例对象在内存中存储分为三块区域,分别是对象头、实例数据、对齐填充。 对象对象头包含两部分,第一部分用于存储对象自身运行时的数据,包括GC分代年龄、哈希码、锁状态、...

    对于HotSpot虚拟机来说,Java类的实例对象在内存中存储分为三块区域,分别是对象头、实例数据、对齐填充。

    对象头

    对象头包含两部分,第一部分用于存储对象自身运行时的数据,包括GC分代年龄、哈希码、锁状态、线程持有的锁等数据,这部分的数据长度在32位和64位虚拟机中分别为32位和64位,被称为“Mark Word”。

    对象头的另一部分用于存储对象的类元数据的指针,虚拟机通过这个指针可以知道对象是哪个类的实例。

    实例数据

    实例数据用于存储在程序代码中定义的各种类型的字段内容,也包含从父类继承来的。这部分数据的存储顺序会受到虚拟机分配策略参数和字段在代码中定义的顺序的影响。

    对齐填充

    在HotSpot虚拟机中,对象的大小要求是8字节的整数倍,因为对象头的大小正好是8字节的一倍或两倍,而实例数据部分可能不是8字节的整数倍,所以需要凑齐8字节的整数倍,就用到了对齐填充部分,它仅仅是用于占位的作用。
    这里写图片描述

    展开全文
  • 对象在内存中存储布局

    千次阅读 2018-10-01 15:52:28
    对象的运行时数据,如哈希码、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等,这部分数据的长度32位和64位的虚拟机(未开启压缩指针)分别为32bit和64bit,官方称它为“Mark Word”。...

     

    对象头中的运行时数据,如哈希码、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等,这部分数据的长度在32位和64位的虚拟机(未开启压缩指针)中分别为32bit和64bit,官方称它为“Mark Word”。

    对象需要存储的运行时数据很多,其实已经超出了32位、64位Bitmap结构所能记录的限度,但是对象头信息是与对象自身定义的数据无关的额外存储成本,考虑到虚拟机的空间效率,Mark Word被设计成一个非固定的数据结构以便在极小的空间内存储尽量多的信息,它会根据对象的状态利用自己的存储空间。例如,在32位的HotSpot虚拟机中,如果对象处于未被锁定的状态下,那么Mark Word的32bit空间中的25bit用于存储对象哈希码,4bit用于存储对象分代年龄,2bit用于存储锁标志位,1bit固定为0,而在其他状态(轻量级锁定、重量级锁定、GC标记、可偏向)下对象的存储内容如下:

    展开全文
  • 对象在内存中存储

    千次阅读 2015-09-20 21:08:37
    类加载创建对象的时候,肯定是需要访问类的 申明1个类的指针变量 也会访问类 只有类第一次被访问的时候,才会做类加载 ...会内存中申请一块空间,内存中声明了一个person类型的指针变量p1. p1是一个
    1. 类加载

      1. 创建对象的时候,肯定是需要访问类的
      2. 申明1个类的指针变量 也会访问类
      3. 只有类在第一次被访问的时候,才会做类加载
        一旦类被加载到代码段以后,直到程序结束的时候才会被释放
        代码段中: 主要是存储person类的代码(类的声明和类实现)

      假设 下面这个代码写在函数之中
      • Person *p1 ;会在栈内存中申请一块空间,在栈内存中声明了一个person类型的指针变量p1.
      p1是一个指针变量,只能存储地址

      • [Person new];真正在内存中创建对象的是这句代码。
      ○ new做的事情
      § 在堆内存中申请一块合适大小的空间
      § 在这个空间中根据类的模板创建对象
      □ 类模板中定义了什么属性,就把这些属性依次的声明在对象之中。对象中还有另外一个属性,叫做isa 指针,指向对象所属的类在代码段当中的地址
      § 初始化对象的属性(付默认值)
      □ 如果是属性的类型是基本数据类型,那么就赋值为0
      □ C语言的指针类型:NULL
      □ OC类指针类型 nil
      § 返回对象的地址

      • 注意:
      ○ 对象中只有属性 而没有方法,自己类的属性外加一个isa指针指向代码段当中的类。
      ○ 如何访问对象的属性
      § 指针名->属性
      § 根据指针 找到指针指向的对象 再找到对象中得属性来访问
      § 如何调用方法:
      [指针名 方法名];
      先根据指针名找到对象,对象发现要调用方法,再根据对象的isa指针找到类

      • 为什么不把方法存储在对象之中?
      ○ 因为每一个对象的代码的实现都是一模一样的,没有必要为每一个对象都保存1个方法,这样的话,太浪费空间了,既然都一样,那么只保存一份。
      • 对象的属性的默认值
      ○ 创建一个对象,没有为对象的属性赋值,那么这个对象的属性是有值的
      § 基本数据类型 0
      § c指针类型 NULL
      § OC 指针 nil

    展开全文
  • Hotspot 虚拟机对象在内存中存储的布局可以分为3块区域:对象头(Object Header)、实例数据(Instance Data)和对齐填充(Padding)。 补充 对象头(Object Header) HotSpot 的对象头由Mark Word和类型指针组成。 ...

    写在前面

    本文隶属于专栏《100个问题搞定Java虚拟机》,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢!

    本专栏目录结构和文献引用请见100个问题搞定Java虚拟机

    解答

    在 Hotspot 虚拟机中,对象在内存中存储的布局可以分为3块区域:对象头(Object Header)、实例数据(Instance Data)和对齐填充(Padding)。
    

    补充

    对象头(Object Header)

    HotSpot 的对象头由Mark Word和类型指针组成。

    Mark Word(标记字段)

    对象自身的运行时数据, 如哈希码(Hash Code)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等。 这部分数据的长度在32位和64位的虚拟机(未开启压缩指针)中分别为32bit和64bit,官方称它为“Mark Word”。

    对象需要存储的运行时数据很多,其实已经超出了32位、64位Bitmap结构所能记录的限度,但是对象头信息是与对象自身定义的数据无关的额外存储成本。 考虑到虚拟机的空间效率, Mark Word被设计成一个非固定的数据结构以便在极小的空间内存储尽量多的信息,它会根据对象的状态复用自己的存储空间。 例如,在32位的Hotspot虚拟机中,如果对象处于未被锁定的状态下,那么Mark Word的32bit空间中的25bit
    用于存储对象哈希码,4bit用于存储对象分代年龄,2bit用于存储锁标志位,1bit固定为0, 而在其他状态(轻量级锁定、重量级锁定、GC标记、可偏向)下对象的存储内容见下表。

    存储内容标志位状态
    对象哈希码、对象分代年龄01未锁定
    指向锁记录的指针00轻量级锁定
    指向重量级锁的指针10膨胀(重量级锁定)
    空,不需要记录信息11GC标记
    偏向线程ID、偏向时间戳、对象分代年龄01可偏向

    压缩指针

    在 64位的Java虚拟机中,对象头的标记字段占64位,而类型指针又占了64位。也就是说,每一个Java对象在内存中的额外开销就是16个字节。

    以Integer类为例,它仅有一个int类型的私有字段,占4个字节。 因此,每一个Integer对象的额外内存开销至少是400%。这也是为什么Java要引入基本类型的原因之一。

    为了尽量较少对象的内存使用量,64位Java虚拟机引入了压缩指针的概念(对应虚拟机选项 -XX:+UseCompressedOops,默认开启),将堆中原本64位的Java对象指针压缩成32位的。

    这样一来,对象头中的类型指针也会被压缩成32位,使得对象头的大小从16字节降至12字节。

    当然,压缩指针不仅可以作用于对象头的类型指针,还可以作用于引用类型的字段,以及引用类型数组。

    类型指针

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

    并不是所有的虚拟机实现都必须在对象数据上保留类型指针,换句话说,查找对象的元数据信息并不一定要经过对象本身。

    如果对象是一个Java数组,那在对象头中还必须有一块用于记录数组长度的数据,因为虚拟机可以通过普通Java对象的元数据信息确定Java对象的大小,但是从数组的元数据中却无法确定数组的大小。

    实例数据(Instance Data)

    实例数据部分是对象真正存储的有效信息,也是在程序代码中所定义的各种类型的字段内容。

    字段重排列

    为了达到内存对齐的目的,Java虚拟机中会重新分配字段的先后顺序,这叫字段重排列。

    Java 虚拟机中有三种排列方法(对应 Java 虚拟机选项 -XX:FieldsAllocationStyle,默认值为 1),但都会遵循如下两个规则。

    1. 如果一个字段占据 C 个字节,那么该字段的偏移量需要对齐至 NC。这里偏移量指的是字段地址与对象的起始地址差值。以 long 类为例,它仅有一个 long 类型的实例字段。在使用了压缩指针的 64 位虚拟机中,尽管对象头的大小为 12
      个字节,该 long 类型字段的偏移量也只能是 16,而中间空着的 4 个字节便会被浪费掉。
    2. 子类所继承字段的偏移量,需要与父类对应字段的偏移量保持一致。在具体实现中,Java 虚拟机还会对齐子类字段的起始位置。对于使用了压缩指针的 64 位虚拟机,子类第一个字段需要对齐至 4N;而对于关闭了压缩指针的 64
      位虚拟机,子类第一个字段则需要对齐至 8N。

    对齐填充(Padding)

    对齐填充起着占位符的作用。

    由于Hotspot虚拟机的自动内存管理系统要求对象起始地址必须是8字节的整数倍,换句话说,就是对象的大小必须是8字节的整数倍。

    而对象头部分正好是8字节的倍数(1倍或者2倍),因此,当对象实例数据部分没有对齐时,就需要通过对齐填充来补全。

    为什么需要对齐填充?

    打个比方,路上停着的全是房车,而且每辆房车恰好占据两个停车位。现在,我们按照顺序给它们编号。

    也就是说,停在 0 号和 1 号停车位上的叫 0 号车,停在 2 号和 3 号停车位上的叫 1 号车,依次类推。

    原本的内存寻址用的是车位号。

    比如说我有一个值为 6 的指针,代表第 6 个车位,那么沿着这个指针可以找到 3 号车。

    现在我们规定指针里存的值是车号,比如 3 指代 3 号车。当需要查找 3 号车时,我便可以将该指针的值乘以 2,再沿着 6 号车位找到 3 号车。

    这样一来,32 位压缩指针最多可以标记 2 的 32 次方辆车,对应着 2 的 33 次方个车位。当然,房车也有大小之分。大房车占据的车位可能是三个甚至是更多。

    不过这并不会影响我们的寻址算法:我们只需跳过部分车号,便可以保持原本车号 * 2 的寻址系统。

    上述模型有一个前提,你应该已经想到了,就是每辆车都从偶数号车位停起。

    类似的,JVM 为了快速的定位到对象的位置,需要引入内存对齐的概念(对应虚拟机选项 -XX:ObjectAlignmentInBytes,默认值为 8)。

    默认情况下,Java 虚拟机堆中对象的起始地址需要对齐至 8 的倍数。如果一个对象用不到 8N 个字节,那么空白的那部分空间就浪费掉了。

    这些浪费掉的空间我们称之为对象间的填充,即对齐填充(padding)。

    展开全文
  • C++对象在内存中存储

    千次阅读 2016-01-02 17:36:43
    最近忽然迷惑,子类继承父类之后,子类对象在内存中存储方式是怎样的。理论上上应该是虚函数表指针、父类变量、子类变量。父类变量存储时是否和子类变量一起实现内存对齐呢? 为了搞明白这个问题,做了如下实验。...
  • Java对象在内存中的布局

    千次阅读 2019-08-08 00:43:17
    虚拟机对象在内存中存储布局可分为三块:对象头、实例数据和对齐填充 1、对象对象头用于存储对象的元数据信息 对象头又可以分为两块内容:第一部分用于存储对象自身的运行时数据,如哈希码...
  • Java 对象在内存中存储

    千次阅读 2015-12-15 01:30:07
    Java 强调: 一切都是对象  尽管如此 但是操纵的标识符实际上是对象的一个引用 借用THINKING IN JAVA 书的例子 : 对象作为电视机 引用就作为遥控器 只要握有这个遥控器 就可以保持与电视机的联系 当...
  • java对象在内存中存储

    千次阅读 2018-02-14 23:05:25
    java对象存储总结一.存储位置我们要对java对象不同的存储位置都有一定了解,会对后续学习有很大帮助。(以下来自java编程思想2.2)1.寄存器:最快的存储区,因为它和其它存储器位于不同位置——处理器内部。缺点是其...
  • OC基础-06 对象在内存中存储细节

    千次阅读 2015-07-08 23:25:05
    OC基础-06 对象在内存中存储细节
  • Java对象在内存中是如何存储

    千次阅读 2016-11-26 21:53:37
    原文地址:How are Java objects stored in memory?Java,所有的对象都被动态地分配堆上。...Java,只有我们申明一个类型变量的时候,只创建一个引用(内存不会为对象分配)。为了给一个对
  • Java对象在内存中存储结构图解

    千次阅读 2019-05-27 19:50:23
    public class TestStudent { public static void main(String[] args) { ... //栈存储 int m = 10; //栈存储 Student stu = new Student(); //属性赋值 stu.name="张三"; System.out.println(stu.name);...
  • java对象在内存中的分配

    万次阅读 多人点赞 2017-02-10 22:45:33
    内存中存放的是new出的对象,new出的对象只包含成员变量。  栈内存中:存放的是局部成员变量。对于基本的数据类型存放的是基本变量的值,而对于对象变量,存放的是堆内存的地址。  静态、常量区:存放的是静态...
  • 变量和对象在内存中如何存储?

    千次阅读 2018-01-23 16:52:04
    但是为什么这个面试题无法调用,a is not a function. 原因是:变量赋值时,a变量存储number10,已经不再指向函数,并且这个函数被销毁. 图解: var a ; var b ; a = {n: 1 } ; b = a ; a .x = a = {...
  • Java对象在内存中实例化的过程

    千次阅读 多人点赞 2020-07-27 15:08:52
    Java对象在内存中实例化的过程 讲 Java 对象在内存中的实例化过程前,先来说下类的实例化过程内存会使用到的三个区域:栈区、堆区、方法区。 堆区: 存储的全部都是对象,每个对象包含了一个与之对应的 ...
  • 2020-05-02:对象在内存中存储布局

    千次阅读 2020-06-11 08:21:17
    福哥口诀法: 头实填 (存储布局:对象头、实例数据、对齐填充) 标类长(对象头:markword标记字、klass类型指针、数组长度(仅限于数组)) 评论
  • 对象和类jvm内存中存储机制

    千次阅读 2019-07-09 12:48:44
    对象和类jvm内存中存储机制 引言: 为什么要有面向对象? a.可以用类组织一批不同类型的数据 b.把现实世界的物和事转换到计算 现实世界的对象--->计算机的类-->计算机内存中对象 要实现面向对象的...
  • javascript-对象在内存中的分配

    千次阅读 2017-01-10 22:53:30
    JavaScript对象有关系的内存区域有四部分组成: 堆空间, 栈空间,数据空间,代码空间。 其中 1. 栈空间 存放的数据大小比较小,一般固定大小的信息适合存放该空间,例 如整型、boolean、对象的引用...
  • Java虚拟机中对象内存的分配情况

    千次阅读 2019-02-20 17:50:16
      前面的文章介绍了对象在虚拟机的创建过程。本文主要是介绍下对象在虚拟机内存布局分配情况...  HotSpot虚拟机对象在内存中存储的布局可以分为3块区域:对象头,实例数据和对齐填充。 对象头 ...
  • 内存中的五大区域  栈---局部变量  堆---程序猿手动申请的字节空间,Malloc calloc readlloc  BBS段----未被初始化的全局变量和静态变量  数据段(常量区)----已经被初始化的全局 静态变量 常量数据  ...
  • 一个 new 对象在内存中的诞生

    千次阅读 2018-02-09 18:55:34
    Persion persion=new Persion一个简单的new对象在内存中的诞生1.生成Persion.class文件通过类加载器加载进内存中2.执行main方法,栈开辟main方法内存空间(压柞-进栈),main最底,栈空间分配了一个变量...
  • C++对象在内存中的存放方式

    千次阅读 2017-03-10 22:19:53
    对象占有一定的内存,该内存上存放的是该对象的相关数据,按先后顺序如下: 1、虚表指针:如果该类有虚函数的话,将存放虚表指针,该指针指向该类的虚函数表,即指向表的第一个元素。续表存放的是该类虚函数的...
  • java对象在内存中的结构

    千次阅读 2018-08-30 15:35:16
    今天看到一个不错的PPT:Build Memory-efficient Java Applications,开篇便提出了一个问题,Hotspot JVM,32位机器下,Integer对象的大小是int的几倍? 我们都知道Java语言规范已经规定了int的大小是4个字节...
  • php对象在内存中的分配

    万次阅读 2015-10-04 15:11:32
    对象的首地址赋给“$p1”这个引用变量,所以$p1 是存储对象首地址的变量,$p1 放在栈内存里边,$p1 相当 于一个指针指向堆里面的对象,所以我们可以通过$p1 这个引用变量来操作对象,通常我们也 称对象引用为对象。...
  • 今天闲来无事,有空闲的时间,所以想坐下来聊一聊Java的GC以及Java对象在内存中的分配。 和标题一样,本篇绝对是用最直接最通俗易懂的大白话来聊 文章基本不会有听起来很高大上专业术语,也不会有太多概念性的...
  • Java变量,对象,字符串等在内存中存储区域
  • Java 对象占用内存大小

    千次阅读 2018-01-22 13:35:25
    HotSpot虚拟机对象在内存中存储的布局可以分为三块区域:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding) java 对象头 Mark Word HotSpot虚拟机的对象头(Object Header)包括两部分信息...
  • 对于JAVA和C#

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,012,180
精华内容 404,872
关键字:

对象在内存中怎么存储