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

时间:2009-03-22 10:08:10

标签: java memory-leaks reference garbage-collection

也许最典型的例子是错误地完成了JDBC关闭而没有正确处理可能的异常。我很好奇看到你见过的其他例子 - 最好是与web应用程序相关。

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

3 个答案:

答案 0 :(得分:17)

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

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

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

答案 1 :(得分:6)

我不会说它很常见 - 在Java中泄漏非常罕见 - 但是由于保留了对非静态内部类的引用而没有使用外部实例,但是我看到了泄漏不管怎么说。

答案 2 :(得分:1)

由于以下原因导致PermGen泄漏:

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

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