首先,我们知道的是每一种数据类型所占用的字节数。比如Integer占用4个字节,Long占用8个字节等。但是实际我们在创建对象的时候,在JVM中的占用的字节数是比这个高的。
一个对象在JVM中的内存布局包含以下内容:

  1. 对象头(Header): 对象头包含两类信息,第一类是用于存储对象自身的运行时数据,如哈希吗,GC分代年龄,锁状态标志,线程持有的锁,偏向线程ID等。 如果JVM是64位,则这部分占用 8个字节,如果JVM是32位,这部分占用4个字节。另外一部分是类型指针,对象指向它的类型源数据指针, JVM通过这个指针来确定对象是哪个类的实例。这部分占用内存的大小和JVM是否开启指针压缩的属性有关,开启 CompressedOops则该数据指针占用内存是 4 位,如果没有开启,就是8位。下面的计算都是按照开启。
  2. 实例数据: 这部分就是对象真正的有效信息。 Long占用8个字节,int占用4个字节等。
  3. 对齐填充(padding):占位符的作用,因为HotSpot虚拟机的自动内存管理系统要求对象的起始地址必须是8字节的整数倍,所以不满8位的数据,会自动补充。所以对象的内存占用都是8的倍数。

关于数组(如char[], int[])

数组的对象头占用空间在原有的对象头上需要多加一个,就是存放数组长度的,占用4个字节。所以一个空的数据,占用的内存是 16个字节。

关于String

Java对象存储在redis中是什么类型 java对象在jvm中的存储_JVM


上面是String的类信息,首先String这个类占用内存大小是 8(对象头)+ 4(指针)

内部包含char[] : 内存大小 8(对象头)+ 4 (指针)+ 4(长度存放)

包含int : 内存大小 4

包含long: 内存大小是 8

所以一个new String(“”)的对象占用内存大小是40 字节。

在char[] 数组中,一个char占用的是2个字节。

综上,一个String类型的数据,在内存中占用的大小是 40 + 2* length附上图:

Java对象存储在redis中是什么类型 java对象在jvm中的存储_JVM_02


另外使用Java代码是可以计算出一个对象的占用内存大小的。