常见的Java内存/引用泄漏模式?

也许最典型的例子是JDBC关闭完成错误的方式,而不是正确处理可能的exception。 我很好奇你能看到的其他例子 – 最好是网络应用程序相关。

那么,Java中是否存在任何常见的泄漏模式?

根据我的经验,两个关键的“有效泄漏”模式是:

  • 随着时间的推移逐渐增长的静力学和单身人士。 这可能包括缓存,实施和使用不良的连接池,“自启动以来我们见过的每个用户”的字典等
  • 从长寿命对象到旨在短暂存在的对象的引用。 在C#中,这可能发生在事件中,并且等效的观察者模式可以在Java中产生相同的效果。 基本上,如果您要求一个对象(观察者)观察另一个对象(源),那么通常最终会得到一个观察者的引用。 这可能最终成为唯一的“实时”参考,但它将与源一样长。
  • 如果您继续动态生成新代码,Permgen会泄漏。 我在这里比较犀利,但我很确定我遇到了这样的问题。 这可能部分归因于JRE错误已被修复 – 它已经太久了,因为它确实发生在我身上。
  • 保持状态的unit testing可能比您预期的更长,因为JUnit将保留在测试用例实例上。 我再也记不起细节了,但有时这会让你在拆解时明确的“变量归零”变得有价值,这看起来不合时宜。

我不能说我经常发现内存泄漏是Java(或.NET)中的一个问题。

我不会说它很常见 – 在Java中泄漏是非常罕见的 – 但是由于保留了对不使用外部实例的非静态内部类的引用,我看到了泄漏,但无论如何都要引用它。

PermGen泄漏可能由于:

  • 取消部署应用程序后保持活动状态的守护程序线程。
  • 在JVM中注册的关闭挂钩
  • ThreadLocal变量,其中值具有对类加载器加载的类的引用

这些都是与Web应用程序相关的。 它们不会发生在标准Java应用程序中。