一、内存布局

对象在内存中存储的结构由三部分组成:对象头、实例数据、对齐填充。

  1. 对象头

    MarkWord(标记字段):哈希码、分代年龄、锁标志位、偏向线程ID、偏向时间戳等信息。Mark Word被设计成了一个非固定的数据结构以便在极小的空间内存储尽量多的信息,它会根据对象的状态复用自己的存储空间。例外:如果是数组的话,还需要有一块区域存放数组大小,因为没办法从元数据确认数组大小,所以要存储到对象头的MarkWord中。

    MarkWord是根据对象的状态区分不同的状态位,从而区分不同的存储结构。例如下图:

    对象头的另一部分是类型指针(Klass Pointer)。

    Klass Pointer(类型指针):即指向当前对象的类的元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例。并不是所有的虚拟机实现都必须在对象数据上保留类型指针,换句话说查找对象的元数据信息并不一定要经过对象本身。

    另外,如果是数组,对象头中还有一块用于存放数组长度的数据,因为虚拟机可以通过普通Java对象的元数据信息确定Java对象的大小,但是从数组的元数据中无法确定数组的大小。其中偏向锁和轻量级锁是java6以后对synchronized进行优化后新增的,稍后做介绍。

  2. 实例数据

    实例数据部分是对象真正存储的有效信息,也就是我们在程序代码里面所定义的各种类型的字段内容,无论是从父类继承下来的,还是在子类中定义的都需要记录下来。 这部分的存储顺序会受到虚拟机分配策略参数(FieldsAllocationStyle)和字段在Java源码中定义顺序的影响。

    HotSpot虚拟机 默认的分配策略为longs/doubles、ints、shorts/chars、bytes/booleans、oops(Ordinary Object Pointers),从分配策略中可以看出,相同宽度的字段总是被分配到一起。在满足这个前提条件的情况下,在父类中定义的变量会出现在子类之前。如果 CompactFields参数值为true(默认为true),那子类之中较窄的变量也可能会插入到父类变量的空隙之中。

  3. 对齐填充

    第三部分对齐填充并不是必然存在的,也没有特别的含义,它仅仅起着占位符的作用。由于HotSpot VM的自动内存管理系统要求对象起始地址必须是8字节的整数倍,换句话说就是对象的大小必须是8字节的整数倍。对象头正好是8字节的倍数(1倍或者2倍),因此当对象实例数据部分没有对齐的话,就需要通过对齐填充来补全。

二、创建过程

在语言层面上,创建对象通常(例外:克隆、反序列化)仅仅是一个 new关键字而已,而在虚拟机中,对象(限于普通Java对象,不包括数组和Class对象等)的创建又是怎样的?

以下分析虚拟机遇到new指令时的操作:

一个对象的存储涉及内存的三部分:方法栈(存储指针)、方法区(存储类信息、常量、静态变量)、堆(存储对象的实例数据)。其中关于最左侧图中“对象的引用”有两种实现方式,如下右图(两种:1、通过句柄实现;2、直接指针实现;):

三、举例

在Hotspot JVM中,32位机器下,Integer对象的大小是int的几倍?

int占用的是4字节。由以上分析可得Integer的结构如下:

Integer只有一个int类型的成员变量value,所以其对象实际数据部分的大小是4个字节,然后再在后面填充4个字节达到8字节的对齐,所以可以得出Integer对象的大小是16个字节。

因此,我们可以得出Integer对象的大小是原生的int类型的4倍。

关于对象的内存结构,需要注意数组的内存结构和普通对象的内存结构稍微不同,因为数据有一个长度length字段,所以在对象头后面还多了一个int类型的length字段,占4个字节,接下来才是数组中的数据,如下:

作者:你是哪块小饼干
链接:https://juejin.im/post/5cc668aff265da037129a8c2
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

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

  1. java对象在内存的大小

    前言 一直以来,对java对象大小的概念停留在基础数据类型,比如byte占1字节,int占4字节,long占8字节等,但是一个对象包含的内存空间肯定不只有这些. 假设有类A和B,当new A()或者n ...

  2. 10 Java 对象的内存布局

    Java 创建对象的方式 1:new 语句和反射机制创建.该方式会调用类的构造器,同时满足诸多约束.如果一个类没有构造器的话,Java 编译器会自动添加一个无参数的构造器.子类的构造器需要调用父类的构 ...

  3. java 对象占用内存

    String 方法用于文本分析及大量字符串处理时会对内存性能造成一些影响.可能导致内存占用太大甚至OOM. 一.先介绍一下String对象的内存占用 一般而言,Java 对象在虚拟机的结构如下:•对象 ...

  4. 灵魂拷问:Java对象的内存分配过程是如何保证线程安全的?(阿里面试)

    JVM内存结构,是很重要的知识,相信每一个静心准备过面试的程序员都可以清楚的把堆.栈.方法区等介绍的比较清楚. 上图,是一张在作者根据<Java虚拟机规范(Java SE 8)>中描述的J ...

  5. JAVA | Java对象的内存分配过程是如何保证线程安全的?

    JAVA | Java对象的内存分配过程是如何保证线程安全的? 专注于Java领域优质技术,欢迎关注 作者 l Hollis 来源 l Hollis(ID:hollischuang) JVM内存结构, ...

  6. Java对象的内存模型(一)

    前言 新人一枚,刚刚入门编程不久,各方面都在学习当中,博文有什么错误的地方,希望我们可以多多交流! 最近,在开发App后台过程中,需要将项目部署到云服务器上.而云服务器的内存大小却只有1G.要如何做到 ...

  7. Java对象的内存布局

    对象的内存布局 平时用java编写程序,你了解java对象的内存布局么? 在HotSpot虚拟机中,对象在内存中存储的布局可以分为3块区域: 对象头 实例数据 对齐填充 对象头 对象头包括两部分信息: ...

  8. JVM总结-java对象的内存布局

    在 Java 程序中,我们拥有多种新建对象的方式.除了最为常见的 new 语句之外,我们还可以通过反射机制.Object.clone 方法.反序列化以及 Unsafe.allocateInstance ...

  9. Java对象的内存(一)

    前言 新人一枚,刚刚入门编程不久,各方面都在学习当中,博文有什么错误的地方,希望我们可以多多交流! 最近,在开发App后台过程中,需要将项目部署到云服务器上.而云服务器的内存大小却只有1G.要如何做到 ...

随机推荐

  1. 学习:CMP/TEST比较指令

    cmp指令:比较 cmp指令,和sub指令的最大的不同点就是影响标志位 不储存结果 1.当前汇编指令为cmp ecx,edx 2.当前ecx寄存器中的地址为00000000,edx寄存器中的地址000 ...

  2. MongoDB shell 4 用户管理方法

    方法名 描述 db.getUsers()   db.dropAllUsers()   db.updateUser()   db.createUser()   db.revokeRolesFromUse ...

  3. CSP-2019酱油记

    炸了 Day0 上午机房弥漫着颓废的气息... nc哥在疯狂打板子,我疯狂找水题找信心(然而被历次联赛T1爆切 退役气息稍重,好多人刷屏cnblogs.. 然后年级扛把子们来做指♂导啦- 准备了火龙果 ...

  4. CSPS_114

    考前自闭赛 综合我100场血的教训,我的考试策略应该是: 1.不要期望能AC某道题,想都不要想,否则很容易直接崩 2.哪怕想到正解,先打暴力,把暴力码出来!没用也码! 稳扎稳打地得到代码难度最小的下一 ...

  5. pwd函数实现

    /* * 文件名:mypwd.c * 描述: 实现简单的pwd命令 */ #include<stdio.h> #include<stdlib.h> #include<di ...

  6. 如何新建WebAPI,生成注释,TestAPI的项目

    一.新建WebAPI的项目 1. 在Web下,ASP.NET Web 应用程序,点击确定 2. 点击确定 3. 如图所示, 新建Controller 4 . 运行项目 二.注释 1. 在生成中,勾选x ...

  7. [Beta阶段]发布说明

    小小易校园微信小程序发布说明 第二版小小易校园小程序发布啦~ 打开微信,点击右上角➕,选择扫一扫,扫描以下二维码即可进入小程序: 版本功能: 上一版功能请参见[Alpha阶段]发布说明. 当前版本的更 ...

  8. 剑指offer:序列化二叉树

    题目描述: 请实现两个函数,分别用来序列化和反序列化二叉树 思路分析: 这里一开始有点不明白题目的意思.实际上序列化应该指把二叉树用某种编码方式表示,这里一般是字符串的形式.而反序列就是将之前生成的序 ...

  9. odoo开发笔记 -- related用法

    related:字面意思-关联字段,表示本字段引用关联表中的某字段. 格式为:fields.related(关系字段,引用字段,type,relation,string,...),关系字段是本对象的某 ...

  10. Centos新服务器需要安装的必备软件包

    yum install -y gcc gcc-c++ kernel-devel yum install -y pcre pcre-devel yum install -y zlib zlib-deve ...