面试题答案
一键面试- 静态集合类导致内存泄漏:
- 场景:使用静态集合类(如
static List
、static Map
等)来存储对象,如果这些对象在程序后续不再使用,但由于静态集合类的生命周期与应用程序相同,这些对象无法被垃圾回收,从而导致内存泄漏。 - 原因:静态变量的生命周期长,只要类被加载,静态集合就一直存在,引用的对象也不会被释放。
- 场景:使用静态集合类(如
- 监听器和回调没有正确移除:
- 场景:在Java中,很多时候会使用监听器(如Swing中的事件监听器)或回调函数。如果注册了监听器或回调,但在不再需要时没有正确地取消注册,那么监听器或回调对象会一直被持有,即使其关联的对象已经不再使用,也无法被垃圾回收。
- 原因:被监听的对象或者回调的发起者一直持有监听器或回调对象的引用,使得垃圾回收器无法回收这些对象。
- 未关闭的资源:
- 场景:例如数据库连接(
Connection
)、文件句柄、网络连接(Socket
)等资源,如果在使用完毕后没有正确关闭。这些资源会一直占用内存,并且可能导致相关的对象无法被垃圾回收。 - 原因:这些资源通常会在底层操作系统层面占用一定的资源,如果Java对象没有释放对这些资源的引用,垃圾回收器无法清理它们,造成内存泄漏。
- 场景:例如数据库连接(
- 内部类持有外部类引用:
- 场景:非静态内部类会隐式持有外部类的引用,如果内部类的实例生命周期比外部类长,当外部类不再需要,但由于内部类的存在,外部类对象无法被垃圾回收。例如在使用线程池时,将一个非静态内部类作为任务提交到线程池,该内部类持有外部类引用,当线程池中的任务未执行完或线程池未关闭时,外部类对象无法回收。
- 原因:内部类对外部类的隐式引用使得垃圾回收器认为外部类对象仍被使用,不能进行回收。