内存泄漏的场景有哪些?
1 个回答
明知不可为而为之就是我最大的诚意沙之影**1. 静态集合类持有对象引用** * 如 `static List/Map/Set`,对象被加入集合但长期不移除,GC 无法回收。 * 场景:缓存设计不当,没有过期策略。 **2. 各种缓存(尤其是自定义缓存)未清理** * 缓存对象长期存活,占用堆空间。 * 解决:使用 `WeakReference`、`SoftReference` 或带过期策略的缓存(如 Caffeine、Guava Cache)。 **3. 监听器、回调未注销** * 注册的事件监听器(Listener/Observer)或回调方法引用未手动移除,导致对象无法释放。 * 常见于 GUI 应用、消息订阅系统。 **4. 线程池/定时任务未关闭** * 线程任务中持有外部对象引用,线程池长期存活,导致对象不被回收。 * 解决:`shutdown()` 线程池,确保任务结束。 **5. 数据库连接、IO 流等资源未关闭** * 虽然不直接导致 Java 堆内存泄漏,但会造成**资源泄漏**,间接影响内存占用。 * 解决:`try-with-resources` 或 finally 中关闭。 **6. 内部类、匿名类持有外部类引用** * 非静态内部类会隐式持有外部类引用,导致外部类无法释放。 * 解决:使用 `static` 内部类,或避免不必要的持有关系。 **7. ThreadLocal 使用不当** * 未调用 `remove()` 清理,线程长时间存活(如线程池线程)时会导致内存泄漏。 **8. 不合理的对象引用链** * 如对象 A 引用对象 B,B 引用 C,C 引用 A,形成循环引用,且外部仍持有其中一个对象。 * 虽然 Java GC 能处理循环引用,但如果引用链一直存在且可达,就不会回收。 **9. 大量 ClassLoader 泄漏** * 动态加载类(如热部署、插件系统)时,旧 ClassLoader 引用未释放,导致相关类和对象都无法回收。 **10. 使用 finalize() 延迟回收** * 对象实现 `finalize()`,且 finalize 执行缓慢,会导致对象长时间滞留在 F-Queue 队列。发布于 2025-08-13 16:49 •IP属地 北京举报评论收藏
公众号进入网站体验更佳

