参考博文: http://www.javamex.com/tutorials/memory/object_memory_usage.shtml

本文主要考虑正常情况下一个对象在堆上的内存占用情况:对于下面的特殊情况不作讨论

1、某些情况下,JVM可能不会把对象存储在堆上:比如小的线程私有对象原则上会全部存储在栈或寄存器上,严格意义上说并不存在于java堆上

2、对象的内存占用可能依赖于它当前的状态,比如说它的同步锁是否处于竞争状态、是否正处于垃圾回收阶段(这些额外的“系统”数据不一定存储在java堆上)

在HotSpot虚拟机上,一个java对象的内存占用一般包括如下几部分:

1、一个对象头部信息(包括几字节的基本元信息)

2、原始类型字段的内存占用

3、引用字段的内存占用

4、对齐字节(padding):为了让每个对象的开始地址是字节的整数倍,减少对象指针占用的比特数,对象数据后面会添加一些“无用”的数据(字节),以实现对齐,即保证最终的字节大小是8的倍数

HotSpot虚拟机的对象头包含两部分信息:1、用于存储对象自身的运行时数据,这部分数据在32位和64位的虚拟机(未开启压缩指针)中分别为32bit和64bit。

2、类型指针,即对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例。注:如果java对象是一个数组,还必须包含用于记录数组长度的数据,因为java虚拟机可以从普通java对象的元数据信息确定对象的大小,但是从数组的元数据中却无法确定数组的大小。

下图描述了32bit下对象头的存储状态:

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

这部分的存储顺序会受到虚拟机的的分配策略参数和字段在java源码中定义的顺序的影响。

java元数据类型占用字节列表:

可能会认为boolean会占用一比特或者占用一个字节的第八位,但是HotSpot虚拟机会为每个Boolean字段分配一个字节的空间。

在HotSpot中,每个对象占用的内存大小是 8 字节的倍数。如果对象所需的内存大小(包括头信息和字段)不是 8 的倍数,则会向上取整到 8 的倍数。

也就是说:

1、一个空对象占用8字节

2、只有一个 boolean 字段的类实例占 16 字节:头信息占 8 字节,boolean 占 1 字节,为了对齐达到 8 的倍数会额外占用 7 个字节

3、包含 8 个 boolean 字段的实例也会占用 16 字节:头信息占用 8 字节,boolean 占用 8 字节;因为已经是 8 的倍数,不需要补充额外的数据来对齐

4、一个包含 2 个 long 字段、3 个 int 字段、1 个 boolean 字段的对象将占用:

  • 头信息占 8 字节;
  • 2 个 long 字段占 16 字节(每个 long 字段占用 8 字节);
  • 3 个 int 字段占 12 字节(每个 int 字段占用 4 字节);
  • 1 个 boolean 字段占 1 个字节;
  • 为了对齐额外多 3 个字节(上面加起来是 37 字节,为满足对齐 8 的倍数 40)

关于二维数组占用字节数计算:注意数组有一个不同的地方在于,它本身会有一个记录数组长度的int类型,占用4字节,本身又是一个对象,会占用8字节

For example, let's consider a 10x10 int array. Firstly, the "outer" array has its 12-byte object header followed by space for the 10 elements. Those elements are object references to the 10 arrays making up the rows. That comes to 12+4*10=52 bytes, which must then be rounded up to the next multiple of 8, giving 56. Then, each of the 10 rows has its own 12-byte object header, 4*10=40 bytes for the actual row of ints, and again, 4 bytes of padding to bring the total for that row to a multiple of 8. So in total, that gives 11*56=616 bytes. That's a bit bigger than if you'd just counted on 10*10*4=400 bytes for the hundred "raw" ints themselves.

关于java内存占用更为详细的描述可以参考廖祜秋大神的博客:http://www.liaohuqiu.net/cn/posts/caculate-object-size-in-java/

廖神的博文中已经指出对于HotSpot,在32位的JVM中,一个对象引用占用4字节,而在64位的JVM中,一个对象引用占用8字节(在开启指针压缩的话占用4字节),而在Dalvik中则是始终占用4字节。

针对Dalvik,元数据类型的大小分别在作为对象域或变量,以及数组的一个元素时是不同的

在Dalvik中对象对齐边界也是8字节,但是一个对象的内存占用和HotSpot是不同的:

会有一个额外的dlmalloc空间占用,4或8字节

所以一个空对象会占用16字节(12字节的内存占用以及4字节的对齐)

示例演示:

class EmptyClass {
}

Total size: 8 (Object overhead) + 4 (dlmalloc) = 12 bytes. For 8 bytes alignment, the final total size is 16 bytes.

class Integer {int value; // 4 bytes } 

The total size is: 8 + 4 + 4 (int) = 16 bytes.

static class HashMapEntry<K, V> { final K key; // 4 bytes final int hash; // 4 bytes V value; // 4 bytes HashMapEntry<K, V> next; // 4 bytes } 

The total size: 8 + 4 + 4 * 4 = 28 bytes. Total aligned is 32 bytes.

详细描述参考廖神博文:http://www.liaohuqiu.net/posts/android-object-size-dalvik/

转载于:https://www.cnblogs.com/CoolRandy/p/5756528.html

关于字节对齐以及内存占用相关推荐

  1. linux c 字节对齐申请内存与字节对齐数组声明

    查找当前系统cache line大小:cat /sys/devices/system/cpu/cpu1/cache/index0/coherency_line_size 函数:void * memal ...

  2. 汉字和数字站几个字节,估算内存占用情况

    中文标点占三个字节,一个英文字母占一个字节,英文标点占一个字节,一个数字占一个字节 字节的换算关系为: 1字节(Byte)=8字位=8个二进制数 1字位(bit)=1个二进制数 1B=8b 1KB=1 ...

  3. malloc内存分配字节对齐问题

    最近看了一些开源的C/C++库,其中都对于内存分配这块做出了自己的一些优化和说明,也涉及到了一些内存分配字节对齐以及内存分页的问题. 对于内存分配的字节对齐问题,一直都是只知其事,不知其解,平时也很少 ...

  4. 字节对齐看这篇就够了(内存对齐)

    前言 大家好,我是小昭,因为在不同硬件平台数据传输时,遇到关于字节对齐的问题,索性就做了总结,以下是我对字节对齐的理解和小结,如有疑问请联系我. 目录 结构体变量占用空间不同 为什么要字节对齐?(内存 ...

  5. 内存对齐/字节对齐/数据对齐/地址总线对齐

    其实是使用InitializeAcl()时发现有个aligned,可我不知道什么是aligned 于是乎我就先搜索了对齐,结果发现了一大堆,什么[字节对齐].[内存对齐].[地址总线 对齐].[数据对 ...

  6. 内存分配,任意字节对齐

    有这么一道题目,要求按任意字节对齐分配内存,接口: char * aligned_malloc(int size, int alignment)//size 为分配的内存大小,alignment对齐基 ...

  7. java字节对齐原则_C struct 中字节对齐问题

    为了提高CPU的存储速度,VC对一些变量的 起始地址做了"对齐"处理.在默认情况下,VC规定各成员变量存放的起始地址相对于结 构的起始地址的偏移量必须为该变量的类型所占用的字节数的 ...

  8. C语言 字节对齐问题 详解

    一  什么是字节对齐 现代计算机中,内存空间按照字节划分,理论上可以从任何起始地址访问任意类型的变量.但实际中在访问特定类型变量时经常在特定的内存地址访问,这就需要各种类型数据按照一定的规则在空间上排 ...

  9. rtthread 字节对齐问题 int指针访问非对齐地址崩溃

    rtthread 字节对齐问题 int指针访问非对齐地址崩溃 环境: SOC: i.MX RT1050 底板: 野火 RT1052 Kernel: rt-thread 背景: 我正在实现解析udp包, ...

最新文章

  1. c++ gets()、scanf() 、getline()、cin读取字符、字符串
  2. 【Java Web开发指南】ELJSTL笔记
  3. 从事数据科学前必须知道的五件事儿
  4. Python入门100题 | 第019题
  5. linux下I2C驱动发送IO时序,I2C驱动情景分析——怎样控制I2C时序
  6. 网站架构之缓存应用(摘录)
  7. UE4笔记-UStructToJsonObjectString首字母自动转换为小写的问题及解决方法
  8. Android/Linux立即从缓冲区写入磁盘
  9. Luogu P2664 树上游戏 dfs+树上统计
  10. 20145239杜文超 《Java程序设计》第3周学习总结
  11. 创客使用Fusion 360 - 认识Fusion 360
  12. NOAA GSOD数据中 国家与地区缩写对应全称
  13. 计算机突然找不到u盘了,win10系统u盘文件突然不见了怎么恢复
  14. 读书笔记(宏微观经济学)
  15. JavaWeb实训项目案例开发之在线图书网站开发【非常适合初学者】
  16. 大数据数据库:MPP vs MapReduce
  17. 第七课:MobileNetv1、MobileNetv2、MobileNetv3学习
  18. 7-4 天长地久 (20分)
  19. 这三种创业项目不要轻易涉足
  20. JavaEE 之 Habernate

热门文章

  1. 中webgl解析json_WebGL蒙皮(下)
  2. 字符串最长公共子序列python_求解两个字符串的最长公共子序列
  3. LeetCode 389. 找不同(位运算)
  4. LeetCode 1154. 一年中的第几天
  5. hbase的2.2.4版本支持哪个版本的hadoop_Hadoop 2.7 不停服升级到 3.2 在滴滴的实践
  6. 专家 安全_船级社专家组到公司开展安全生产标准化考核
  7. phppage类封装分页功能_PHP封装的page分页类定义与用法完整示例
  8. Stage划分和Task最佳位置
  9. python节日贺卡图片大全_新年贺卡图片_新年贺卡手工制作图片
  10. 干货 | 带你理解对比学习损失函数的性质以及温度系数的作用