MST

星途 面试题库

面试题:Java抽象类内存管理与继承关系处理

当一个非抽象子类继承自抽象类时,在内存管理方面,Java是如何协调抽象类和子类的资源分配与释放的?请结合具体的内存区域(如堆、栈、方法区等)进行说明。
20.7万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试
  1. 对象创建与堆内存
    • 抽象类部分:虽然抽象类不能直接实例化,但当非抽象子类实例化时,抽象类中定义的成员变量(无论是基本类型还是引用类型)会在堆内存中为其分配空间。例如,若抽象类 AbstractClass 有一个 int 类型变量 num 和一个引用类型变量 objRef,子类 SubClass 继承自 AbstractClass。当 SubClass sub = new SubClass(); 执行时,numobjRef 会在堆中与 SubClass 自身的成员变量一起分配内存。
    • 子类部分:子类自己声明的成员变量同样在堆内存中分配空间。如 SubClass 有一个 String 类型变量 subStr,也会在堆中分配内存。
  2. 方法调用与栈内存
    • 抽象类方法:抽象类中的非抽象方法在方法区中存储字节码。当子类实例调用从抽象类继承来的非抽象方法时,该方法的调用栈帧会在栈内存中创建。例如,抽象类 AbstractClass 有一个非抽象方法 printInfo,子类 SubClass 继承后调用 sub.printInfo();,此时在栈中会为 printInfo 方法创建栈帧,包含方法参数、局部变量等信息。
    • 子类方法:子类重写或新增的方法字节码也在方法区存储。当调用子类自己的方法时,同样在栈内存中创建相应的栈帧。如 SubClass 有一个 subMethod 方法,调用 sub.subMethod(); 时,栈中为 subMethod 创建栈帧。
  3. 资源释放
    • 堆内存:当对象不再被引用(如将对象赋值为 null),Java 的垃圾回收机制(GC)会在适当时候回收堆内存。无论是抽象类部分的成员变量占用的堆内存,还是子类成员变量占用的堆内存,只要没有活跃引用,都会被 GC 标记并回收。例如,sub = null; 后,SubClass 对象及其从抽象类继承的成员变量所占用的堆内存都可被回收。
    • 栈内存:方法执行完毕,其在栈内存中的栈帧会自动弹出释放。无论是抽象类方法还是子类方法,执行结束后,栈帧中的局部变量等资源都会被释放。比如 printInfosubMethod 方法执行完,其栈帧从栈中移除。
  4. 方法区:方法区中的字节码信息(包括抽象类和子类的方法字节码)在类加载后存在,当类卸载时(通常在应用程序结束或类加载器被释放等特殊情况下),方法区中对应的类相关信息(包括字节码等)才会被释放。