功能相同的普通类、抽象类与接口,哪个内存占用最小?
普通类、抽象类与接口的内存占用对比
嘿,这个问题问得很到位!咱们得从「类元数据内存」和「实例内存」两个维度来拆解,因为这三者的性质本身就不一样:
1. 接口(IStudent)的内存情况
接口本身不能被实例化,所以不存在「实例内存」这一说。
从JVM存储的类元数据来看,接口的结构是最简洁的:
- 它的
name是静态常量(接口里的字段默认就是public static final),会被存在方法区的常量池中,不属于实例属性; - 它只有抽象方法的签名,没有方法的具体字节码实现;
所以接口的元数据内存占用是三者里最小的。
2. 抽象类(AStudent)的内存情况
抽象类同样不能直接实例化,必须由子类实现抽象方法后才能创建子类实例。
- 元数据方面:抽象类比接口多了实例字段的定义(这里的
name是实例级的final字段)、默认构造器的字节码,虽然有抽象方法,但整体元数据占用比接口大,比普通类小; - 实例内存方面:如果有子类继承
AStudent并实现callMe方法,子类实例的内存和普通类Student的实例几乎一致——因为实例内存主要由对象头和实例字段决定,两者都只有一个name引用字段,所以实例占用的内存差别可以忽略。
3. 普通类(Student)的内存情况
普通类可以直接实例化:
- 元数据方面:它包含了
callMe方法的完整字节码实现,还有实例字段、构造器等,所以元数据内存比抽象类略大一点; - 实例内存方面:每个
Student实例包含对象头(Mark Word、类型指针等)和name字段的引用(指向常量池里的空字符串),和抽象类子类实例的内存占用基本相同。
总结
- 如果看类本身的元数据内存:
IStudent(接口) <AStudent(抽象类) <Student(普通类) - 如果看实例内存:接口没有实例;抽象类本身无实例,其合法子类的实例和普通类实例内存占用几乎一致
内容的提问来源于stack exchange,提问作者Freelancer
相关产品推荐
相关产品推荐

