含自身引用的Java Base类对象创建时的内存分配机制
Java中包含自身类型成员的类的内存分配逻辑
你之前的误区在于把引用类型成员变量当成了对象实例本身,实际上Java里的引用类型变量存的只是指向堆中对象的地址,不是对象的全部内容,所以不会出现Base = Base + a + c的矛盾。
单个Base实例的内存组成
对于你定义的Base类:
class Base { Base b; int a; int c; }
一个Base实例在堆中的内存由以下部分组成:
- 对象头:包含Mark Word(存储哈希码、锁状态等)和类型指针(指向类元数据),大小取决于JVM架构:32位JVM约8字节,64位JVM默认16字节(开启指针压缩后为12字节)。
- 成员变量区:
Base b:这是一个引用,32位JVM占4字节,64位JVM默认8字节(开启指针压缩后4字节),默认值为null(不指向任何对象)。int a和int c:每个int占4字节,共8字节。
- 内存对齐:JVM会按8字节或16字节的规则对对象内存进行对齐,补足剩余空间。
实际分配过程
当你执行Base obj = new Base()时:
- JVM在堆中为这个
Base实例分配一块固定大小的内存(比如64位开启指针压缩后,对象头12字节+引用4字节+两个int共8字节=24字节,刚好对齐)。 - 实例中的
b成员只是一个空引用,并没有额外创建Base对象,所以不存在无限递归分配的问题。 - 只有当你主动给
b赋值(比如obj.b = new Base())时,JVM才会在堆中再分配一块独立的Base实例内存,新实例的b同样是null,两个实例完全独立,各自的内存大小固定。
简单说:每个Base实例的大小是固定的,b只是一个指向其他实例(或null)的指针,不会把整个对象嵌套进去。
内容的提问来源于stack exchange,提问作者Gokul Gadkar
相关产品推荐
相关产品推荐

