JVM在创建对象的时候,会有一个内存对齐的概念

  1. 一个空对象占用8字节( 空对象:占8字节 64位bit )
  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 个字节;
上面加起来是 37 字节,
为了对齐额外多的 3 个字节,需求对齐 ,为8 的倍数 40

CPU高速缓存行

计算机访问内存的两种方式:
从为word_size(比如32位或者64位)的倍数的地址开始

  1. 读取长度为word_size的内存块的数据
  2. 把长度为word_size的数据写入内存。

这里有两个“天性”

  1. 读/写总是从word_size的倍数的地址开始的
  2. 读/写的长度总是word_size的倍数

比如在一台64位的计算机上,读取一块1k的内存,CPU需要进行的读取操作次数是:
JVM内存对齐 - 图1
从内存中一次取出32bit(4字节)、64bit(8字节),若一个变量刚好占这么多内存是理想的。
image.png
若数据与缓存行大小不一致,将存储在两行间。
image.png

内存对齐的意义

并非单纯的读取/写入性能。
并发操作数据时,锁定指令是否会同时锁住两条记录。