类是蓝图,对象是依蓝图创建的内存实例;类定义仅生成元数据不占实例内存,new调用时在堆分配内存、清零并执行构造函数,对象存字段副本而共享方法代码,GC回收无引用对象但类元数据常驻。

类是蓝图,对象是根据这个蓝图在内存中创建出来的具体实例。这个过程不是凭空发生的,而是由编程语言的运行时系统(比如 JVM、Python 解释器或 .NET CLR)按规则执行的一系列内存操作。
类定义阶段:只存结构,不占对象内存
当你写 class Person: 或 public class Person { } 时,编译器/解释器会解析语法,生成类的元数据(如方法表、字段偏移量、继承关系等),并加载到方法区(JVM)或类型对象区(Python/CLR)。此时没有任何 Person 对象被创建,也不分配堆内存。
这就像建筑师画好图纸——图纸本身不是房子,也不能住人。
new / 构造调用阶段:触发内存分配与初始化
执行 new Person()、Person() 或 malloc + 构造函数 时,运行时做三件事:
- 在堆上分配连续内存块:大小 = 所有实例字段(非静态)的字节总和 + 对齐填充 + 隐式对象头(如 JVM 的 Mark Word 和 Class Pointer)
- 将内存清零(默认初始化):数值型字段为 0,引用型为 null,布尔为 false
- 调用构造函数执行自定义初始化:给字段赋值、申请资源、设置状态等
完成后,该内存块就成为一个“活”的对象实例,栈上(或寄存器中)通常保存一个指向它的引用(指针)。
对象存在期间:数据与行为绑定在内存实体上
每个对象实例拥有自己独立的字段副本(存储在堆中),但所有同类型对象共享同一份方法代码(存于方法区/代码段)。调用 p1.getName() 时,实际是:
- 通过 p1 引用找到堆中对应对象地址
- 查该对象头里的类指针,定位到 Person 类的方法表
- 取出 getName 方法入口,传入当前对象(this)作为隐式参数执行
这就是“同一个蓝图,多个独立实例,共用一套行为逻辑”的内存本质。
销毁与回收:实例生命周期结束
当对象不再被任何活动引用可达(如局部变量出作用域、引用被置 null),它就变成垃圾。GC 线程后续会在安全点扫描堆,识别并回收这些内存块。类的元数据则通常长期驻留,除非类加载器被卸载(如热部署场景)。
对象消亡不等于蓝图消失——删掉一栋楼,不影响图纸还放在档案馆里。















