如何在Java中存储引用

如何在Java中存储引用,java,memory-management,jvm,heap-memory,Java,Memory Management,Jvm,Heap Memory,我开始深入研究JVM、内存管理和对象的存储方式。到目前为止,我知道当创建一个新对象时,object a=new object()a存储在堆栈内存中,并保存对对象本身的引用(在堆内存中的位置) 那很好。但是我想知道引用的地址存储在哪里。如何访问此引用?我的假设是“a”保存引用所在的第一个字节的地址,因为它是一个对象引用,所以假设它有8个字节长 这是我想象中正在发生的事情的视觉效果 如果有人能给我一个更详细的解释,或者如果我错了,给我一个正确的解释,或者给我一篇关于它的文章,我将不胜感激 现在我要

我开始深入研究JVM、内存管理和对象的存储方式。到目前为止,我知道当创建一个新对象时,
object a=new object()
a
存储在堆栈内存中,并保存对对象本身的引用(在堆内存中的位置)

那很好。但是我想知道引用的地址存储在哪里。如何访问此引用?我的假设是“a”保存引用所在的第一个字节的地址,因为它是一个对象引用,所以假设它有8个字节长

这是我想象中正在发生的事情的视觉效果

如果有人能给我一个更详细的解释,或者如果我错了,给我一个正确的解释,或者给我一篇关于它的文章,我将不胜感激


现在我要解释更多的问题,比如:你怎么知道物体的大小?这是否存储在对象头的某个位置?

除了特殊情况(如转义分析)之外,对象都是在堆上分配的

创建对另一个对象的引用时,可以将其指定给局部变量(存储在堆栈上)或实例/类字段,在这种情况下,它存储在保存引用的对象内

引用指向堆上的某个位置,并由Java运行时自动取消引用。在纯Java中,您无法访问原始指针或检查对象大小的简单方法

存储在堆上的实际数据/结构从通常称为对象头的内容开始。标头包含一个(压缩的)类指针,指向定义类布局的内部数据结构(存储在称为元空间的单独内存区域中,如果使用压缩的OOP,则存储在压缩的类空间中)

指针可以是4或8个字节,这取决于体系结构-即使在64位系统上,由于优化,它通常是4个字节

可以使用打印对象布局


最后,Alexei Shipilev的这个帖子包含了更多关于java对象布局的细节:

java中的引用基本上是C或C++中的指针,只是没有能力对它们进行算术运算。“在哪里存储引用的地址”:引用在堆栈中,在当前堆栈帧内的已知偏移中;或者它位于对象或类内部,同样位于已知偏移量处。你不需要它的地址。对象大小是类的一个属性,每个对象都有一个对自己类的引用。局部变量根本不必在内存中;它可以保存在CPU寄存器中。在优化器生成执行预期操作的代码后,它甚至可能不再存在。对于大多数JVM实现,对象大小仅取决于类,因此,由于所有对象都有对其类的引用,因此不需要在每个对象中存储该大小。