首页 > 系统相关 >美团面试:如何计算一个对象在内存中占多少个字节?

美团面试:如何计算一个对象在内存中占多少个字节?

时间:2024-07-23 14:18:38浏览次数:9  
标签:00 Java 字节 对象 美团 内存 对齐

在分配对象的时候会有一些基本的规则,我们可以根据一些规则大致能判断出来对象大小。

对象总述

在 Hotspot VM 中,对象在内存中的存储布局分为三个区域:

  1. 对象头(Header)
  2. 实例数据(Instance Data)
  3. 对齐填充(Padding)

对象头(Header)

对象头包括以下三部分:

  1. MarkWord:用于存储对象运行时的数据,例如 HashCode、锁状态标志、GC 分代年龄等。在 64 位操作系统下占 8 字节,32 位操作系统下占 4 字节。
  2. 元数据指针:指向对象的类元数据的指针,虚拟机通过这个指针确定该对象属于哪个类。在开启指针压缩的情况下占 4 字节,未开启时占 8 字节。
  3. 数组长度:仅在数组对象中存在,占 4 字节。非数组对象不包含这一部分。

实例数据(Instance Data)

用于存储对象中的各类字段信息,包括从父类继承而来的字段。

对齐填充(Padding)

Java 对象的大小默认按照 8 字节对齐,也就是说 Java 对象的大小必须是 8 字节的倍数。如果对象大小不足 8 字节,则进行填充以满足对齐要求。

8 字节对齐的原因

8 字节对齐并不是浪费空间资源,主要有以下原因:

  1. CPU 内存访问效率:CPU 进行内存访问时,一次寻址的指针大小是 8 字节,正好与 L1 缓存行的大小一致。如果不进行内存对齐,可能会出现跨缓存行的情况,这会导致缓存行污染,影响性能。
  2. 提高内存访问速度:内存对齐可以提高数据访问的速度,因为对齐的数据可以在一个内存访问周期内读取完毕,而未对齐的数据可能需要多个周期。

通过 8 字节对齐,可以减少 CPU 访问内存时的额外开销,从而提升整体性能。

没有字段对齐
由于当 obj1 对象的字段被修改后,那么 CPU 在访问 obj2 对象时,必须将其重新加载到缓存行,因此影响了程序执行效率。

也就说,8字节对齐,是为了效率的提高,以空间换时间的一种方案。固然你还能够 16 字节对齐,可是 8 字节是最优选择。

Java 对象到底占用多大内存

前面我们分析了 Java 对象到底都包含哪些东西,所以现在我们可以开始剖析一个 Java 对象到底占用多大内存。

由于现在基本都是 64 位的虚拟机,所以后面的讨论都是基于 64 位虚拟机。 首先记住公式,对象由 对象头 + 实例数据 + padding 填充字节组成,虚拟机规范要求对象所占内存必须是 8 的倍数,padding 就是干这个的。
从 JDK 8 开始,HotSpot JVM 默认开启了指针压缩(Compressed Oops)。指针压缩可以减少对象指针的大小,从而节省内存空间,提高内存访问的效率。

一个空的Java object 对象占多大内存?

一个空的对象,在开启压缩指针的情况下,占16个字节。其中Markword占8个字节、类元指针占4个字节, 对齐填充占4个字节。

简单类

public class Test {

    private int a;

    private long b;

    private byte c;

}

要占用的空间为:

head(8+4) + a(4) + b(8) + c(1) + padding(7) = 32

对象包含基础数据和引用对象

public class Test { 
    byte a; 
    int b; 
    boolean c; 
    long d; 
    Object e; 
} 

要占用的空间为:
Object e 存的是地址,占用4字节。

head(8+4) + a(1) + b(4) + c(1) + d(8) + e(4) + padding(2) = 32

通过以上规则和例子,可以帮助我们大致判断Java对象在内存中占用的空间大小。

如何验证估算是否正确

org.openjdk.jol:jol-core:0.9 是一个 Java 库,用于分析和探索 Java 对象布局(JVM 内存布局),帮助理解对象在内存中的实际占用情况。
使用如下:

<dependency>
  <groupId>org.openjdk.jol</groupId>
  <artifactId>jol-core</artifactId>
  <version>0.14</version>
</dependency>

示例代码:

package com.trace.agent;

import org.openjdk.jol.info.ClassLayout;

import java.util.List;


public class Test {

    public static void main(String[] args) {
        ClassLayout classLayout = ClassLayout.parseInstance(new ObjectA());
        System.out.println(classLayout.toPrintable());
    }
}


class ObjectA {
}

输出如下:

com.trace.agent.ObjectA object internals:
 OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
      0     4        (object header)                           01 00 00 00 (00000001 00000000 00000000 00000000) (1)
      4     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
      8     4        (object header)                           56 f3 00 jp (01000011 11000001 00000000 11111000) (-13311823)
     12     4        (loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

以上代码和输出示例说明了如何使用 JOL 库来验证 Java 对象在内存中的实际占用情况。通过这些工具和方法,可以更准确地分析和理解 Java 对象的内存布局。

标签:00,Java,字节,对象,美团,内存,对齐
From: https://www.cnblogs.com/codewd/p/18318297

相关文章

  • 微信小程序 - 最新详细实现 “餐厅食堂外卖点餐“ 全屏左右联动菜单列表功能界面,附带
    前言如果您需要“简约通用”的左右联动功能,请访问这篇文章。在微信小程序开发中,详解实现仿饿了么、美团外卖用户点餐左右联动界面,全屏适配左边菜单分类右侧商品菜单列表数据,顶部是搜索栏可搜索定位对应锚点位置及商品,左侧导航菜单点击时右侧商品跟着变化,反之列表滑动......
  • 驱动开发系列07 - 驱动程序如何分配内存
    一:概述        Linux内核提供了丰富的内存分配函数、在本文中,我们将介绍在设备驱动程序中分配和使用内存的方法,以及如何优化系统的内存资源。由于内核为驱动程序提供了统一的内存管理接口。所以我们不会去讨论不同架构是如何管理内存的,文本不涉及分段、分页等问题,此......
  • 如何选择天津拓航科技的反射内存卡
    选择反射内存卡时,需要考虑以下几个关键因素:1.传输速度和延迟:根据您的应用对数据实时性的要求,选择具有合适传输速度和低延迟的反射内存卡。如果是对时间要求极为苛刻的系统,如航空航天仿真、高速工业控制等,应优先选择具有纳秒级延迟和高传输速率的产品。2.内存容量:确定所需的内存......
  • 天津拓航科技有限公司反射内存卡原理说明
    一、引言反射内存卡是一种用于实现高速数据共享和实时通信的先进技术。它在多个领域,特别是对数据传输速度和实时性要求极高的应用中,发挥着关键作用。二、基本原理1.共享内存模型①反射内存卡创建了一个共享的内存区域,多个连接到网络的节点都可以访问这个区域。②当一个节......
  • 如何使用天津拓航科技反射内存卡
    硬件安装:1.确认计算机有相应的插槽,如PCI插槽(以PCI5565反射内存卡为例),可打开机箱查看主板上是否预留。2.设置反射内存卡上的S1和S2值。S1是8位开关,例如第一位控制反射内存是否打开冗余模式,第二位控制是否打开高性能开关,第三和第四位一起控制需要使用的反射内存空间大......
  • 反射内存卡驱动的安装
    反射内存卡驱动的安装通常遵循以下一般步骤,但具体过程可能因产品型号和操作系统的不同而有所差异:1.准备工作-确认您的操作系统版本和体系结构(32位或64位)。-从反射内存卡制造商的官方网站下载适用于您的操作系统的最新驱动程序。2.解压驱动文件-将下载的驱动压缩包解压......
  • 4、内存品牌分类介绍(海盗船) - 计算机硬件品牌系列文章
    海盗船(‌Corsair)‌是一家位于美国加利福尼亚州佛利蒙的私有公司,‌成立于1994年,‌由DonLieberman、‌JohnBeekley与AndyPaul创立。‌海盗船内存(‌CorsairMemory)‌,‌国内又称海盗旗,‌是高性能内存解决方案的先驱者,‌以其超稳定内存产品而在业界声名远播。‌该品牌的产品在极......
  • SUMA&国产海光平台服务器32DB16主板ECC内存对应表&故障内存定位
    32DB16主板内存映射关系,在ECC报错后,可参考LinuxHWError及EDAC等OS信息,定位出错内存所在位置。一、关于主板型号如何确认?方法一:可以使用以下命令在Linux系统进行查看,sudodmidecode-tbaseboard也可以使用cat/sys/class/dmi/id/board_vendorcat/sys/class/dmi/id/bo......
  • 反射内存交换机的应用案例
    1.工业自动化:在生产线上连接多个控制器、传感器和执行器,实现生产过程的实时监控和协调控制。例如,汽车制造工厂中,用于控制机器人的动作、监测设备状态以及实时调整生产参数,以提高生产效率和产品质量。2.航空航天领域:飞行模拟器、飞行器的控制系统以及卫星地面站等都可以用到反射......
  • 引领数据传输革命:反射内存交换机——为您开启极速、稳定、高效的通信新时代
    在当今数字化、信息化的浪潮中,数据已成为企业和组织最宝贵的资产之一。而在数据驱动的世界里,快速、准确、稳定的数据传输则是实现业务成功的关键。反射内存交换机,作为数据通信领域的尖端技术,正以其卓越的性能和创新的设计,重塑着数据传输的未来,为您的业务带来前所未有的机遇和突破......