JVM在创建对象的时候,会有一个内存对齐的概念
- 一个空对象占用8字节( 空对象:占8字节 64位bit )
- 只有一个 boolean 字段的类实例占 16 字节:头信息占 8 字节,boolean 占 1 字节,为了对齐达到 8 的倍数会额外占用 7 个字节
- 包含 8 个 boolean 字段的实例也会占用 16 字节:头信息占用 8 字节,boolean 占用 8 字节;因为已经是 8 的倍数,不需要补充额外的数据来对齐
- 一个包 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位)的倍数的地址开始
- 读取长度为word_size的内存块的数据
- 把长度为word_size的数据写入内存。
这里有两个“天性”
- 读/写总是从word_size的倍数的地址开始的
- 读/写的长度总是word_size的倍数
比如在一台64位的计算机上,读取一块1k的内存,CPU需要进行的读取操作次数是:
从内存中一次取出32bit(4字节)、64bit(8字节),若一个变量刚好占这么多内存是理想的。
若数据与缓存行大小不一致,将存储在两行间。
内存对齐的意义
并非单纯的读取/写入性能。
并发操作数据时,锁定指令是否会同时锁住两条记录。
