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

也许最典型的例子是JDBC关闭错误的方式,并且没有正确处理可能的异常。我很好奇看到你看到的其他例子 - 最好是与Web应用程序相关的。

那么,Java中有什么常见的泄漏模式吗?


答案 1

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

  • 随时间逐渐增长的静态和单例。这可能包括缓存,实现不当和使用连接池,“自启动以来我们看到的每个用户”的字典等。
  • 从长寿命对象到旨在短期存在的对象的引用。在 C# 中,这种情况可能发生在事件中,等效的观察者模式可以在 Java 中产生相同的效果。基本上,如果你要求一个对象(观察者)观察另一个对象(源),那么你通常最终会得到观察者的引用。这可能最终成为唯一的“实时”参考,但它将与源一样长。
  • Permgen 泄漏,如果你继续动态生成新代码。我在这里的地面更崎岖,但我非常确定我以这种方式遇到了问题。这可能部分是由于JRE错误已经修复 - 自从它发生以来,我已经很久了,我无法确定地记住。
  • 保持状态的单元测试可以比您预期的持续时间更长,因为JUnit将保留测试用例实例。同样,我不记得细节,但有时这使得在拆解中明确“变量空化”是值得的,因为看起来不合时宜。

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


答案 2

我不会说这很常见 - 泄漏在Java中非常罕见 - 但是我已经看到了一个泄漏,因为保留了对非静态内部类的引用,该类没有使用外部实例,但无论如何都保留了对它的引用。