测试和解释内存对齐(java)

对象大小

 主要由3个部分组成,包括对象头、实例变量和内存填充。如图所示:
在这里插入图片描述

注意:

  1. 对象头和虚拟机位数有关。在32位虚拟机下,对象头为8字节(包括4字节的Class指针和4字节的MarkWord。在64位虚拟机下,对象头为16字节(包括8字节的Class指针和8字节的MarkWord。如果64位开启指针压缩的情况下,存放Class指针的对象头为12字节(因为其中 的Class指针被压缩成4字节)。
  2. 实例对象即类中所定义的各种类型的字段内容。例如:
在这里插入图片描述
  3. 内存填充:用来保证(对象头+实例变量)的字节数必须是8的倍数。

基本数据类型长度

在这里插入图片描述

查看对象在堆上面开辟的大小:

思路:
 mian函数设置为死循环,程序不结束就可以找到对应实体。生成log文件,便可查看占用空间大小。
步骤:
  1.用记事本新建两个java文件,放在同一路径。
TestDemo.java

public class TestDemo{
    
    
	public static void main(String[] args){
    
    
		People p=new People();//注意P大写
		while (true){
    
    
		}
	}
}

  People.java

class People{
    
    
	int a;
	int b;
	int c;
	byte d;
}

  2.在java文件所在目录的搜索框里输入cmd,打开两个DOS界面备用。
在这里插入图片描述

  3.第一个cmd里:依次输入javac TestDemo.javajava TestDemo,对java文件进行编译和运行。
在这里插入图片描述
  在第二个cmd里,依次输入jps(用来查看TestDemo进程号)和jmap -histo:live 进程号>inform.log(生成日志文件)
在这里插入图片描述

  4.然后在java文件所在目录里查看刚才生成的inform文件。
在这里插入图片描述

  5.搜索关键词People就能看到虚拟机为该类开辟的空间大小。
  6.注意TestDemo.java是死循环,得到logn文件后在dos界面输入ctrl+c终止该程序。
在这里插入图片描述

大小分析:

 由于指针压缩,对象头是12个字节;People类里有3个int和1个byte变量,共4*3+1=13个字节 。12+13=25不是8的倍数,系统给它内存填充7个,所以总大小为32。
 其实内存中的Class文件是以字节流的形式存储的。所有16bit、32bit和64bit的数据分别都是通过读取2bytes、4bytes和8bytes的内存空间来构造存储的。多字节数据项总是以高位顺序存储,高字节优先。Java中最大的数据类型long和double都是占8bytes,所以以最大的8bytes为单位来进行内存分配。

内存对齐的好处

 1.平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据,某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常
  2.硬件原因:经过内存对齐之后,简化了处理器和内存接口的设计,可使CPU的内存访问速度大大提升。假设一个处理器要从内存中读取8bytes的数据A,则A地址必须是8的倍数,这样就可以用一个内存操作来读或者写这个A了。否则,我们可能需要执行两次内存访问,因为A可能被放在了两个8bytes的内存块中。
 内存对齐其实就是空间换时间的思想。毕竟CPU比内存快了几个数量级。

参考资料:

The Java® Virtual Machine Specification
为什么要内存对齐?
内存对齐规则
对象内存布局
CPU和内存速度对比

猜你喜欢

转载自blog.csdn.net/qq_41571459/article/details/113125973