【问题标题】:Memory Leak in a Java based application基于 Java 的应用程序中的内存泄漏
【发布时间】:2011-05-01 23:22:03
【问题描述】:

当一个短期对象持有一个长期对象时,应用程序中会发生内存泄漏, 我的问题是我们如何识别 1) 哪个物体的寿命更长和更短,有什么工具可以测量物体的寿命?

第二个问题

我经常收到 Out of Memory Space 错误,我尝试将堆内存增加到 2 GB,但我仍然得到,请向我推荐任何可以识别内存泄漏问题并修复的开源工具。

目前我每次都重新启动服务器作为临时解决方案,但建议我任何可以永久修复的东西。

【问题讨论】:

  • “当一个短命的物体拥有一个长命的物体时”是什么意思?当长期对象(如静态映射)持有对应该是短期对象的不必要引用时,垃圾收集环境中的内存“泄漏”就会发生。

标签: java performance memory-management memory-leaks


【解决方案1】:

【讨论】:

    【解决方案2】:

    有两种选择:

    • 这可能是您的应用程序没有分配足够的堆。测量输入的大小并为应用程序提供相应的堆;

    • 存在内存泄漏:使用分析器,检查您的堆,找到不应该存在或存在过多的对象(用您的话来说是“短期对象”),确定哪些“长期存在” living' 对象持有他们,解决这个问题。您应该了解您的代码以了解哪些对象必须是“短期的”,哪些必须是“长期的”。

    【讨论】:

    • 我几乎分配了 2 GB 的空间,之前只有 15 个用户在使用,现在用户数增加到 50 多个,从那时起我收到此错误。
    【解决方案3】:

    我发现 Netbeans 中的 Heap Walker 非常有用

    【讨论】:

      【解决方案4】:

      如前所述,jvisualvm 有很好的工具来实时分析堆。

      但您也可以使用 jvisualvm 或 -XX:+HeapDumpOnOutOfMemoryError 在文件中进行堆转储。然后将文件带到您的 destkop,在Eclipse Memory Analyzer 中打开它。 Eclipse MAT 更适合分析内存。

      【讨论】:

        【解决方案5】:

        内存不足发生在服务器上,因为它实际上用尽了它允许拥有的所有内存。不确定您使用什么应用程序来托管服务器,但对于 Apache,您需要添加 -Xmx512m 行,其中 512 是它允许拥有的最大兆字节数。

        如果您让应用程序运行足够长的时间,它就会发生。这不是因为 Java 中的内存泄漏,而是服务器本身倾向于这样做。您无法更改此行为,但您至少可以增加 256 mb 的默认内存。对于我每天工作的重载站点,不幸的是,256 mb 对我来说持续了大约 30 分钟。我发现 1024 mb 是合理的,很少会因为内存不足异常而崩溃。

        我觉得 Java 无法正确收集垃圾是非常不寻常的,除非程序员着手覆盖典型功能。

        【讨论】:

        • 静态字符串常量是否占用大量内存?
        • 任何静态变量都放在堆上,而不是堆栈上,这意味着它们会持续存在。但是,当 jar 卸载时,大多数(体面的)jvm 会将其从堆中删除。虽然有一件事是肯定的:这本身不会导致内存不足异常。
        【解决方案6】:

        我认为您可以使用 jsconsole 跟踪内存泄漏(如果我没记错的话,它随 JDK6 一起提供)。

        【讨论】:

          【解决方案7】:

          持有对长寿命对象的引用的短寿命对象不会引起问题。 (一个很好的 overview ,包括分代垃圾收集)。

          2GB 是非常多的对象/引用。如果您的 2Gb 堆空间用完,您可能会保留大量数据和/或在使用完这些数据后保持开放资源。您至少应该发布一份说明,说明您的应用程序做了什么以及需要多长时间才能死掉。

          您可以通过观察垃圾收集器快速了解正在发生的事情(例如,使用“-verbose:gc”运行它会告诉您垃圾收集器何时运行以及它收集了多少)。

          【讨论】:

          • 是因为将所有常量创建为静态名称值对吗?例如 Public static final String ENGG_SOUTH_DIVISION = "South";
          • 您键入的任何内容都不足以与您看到的内存量有任何关系。为了向自己证明这一点,请编写一个循环,将一百万左右不同的字符串放入一个集合或哈希图中——您应该能够轻松地将其放入远小于 2GB 的空间中。如果您要填满 2GB,那么您输入的常量甚至都不是舍入错误。
          猜你喜欢
          • 2013-04-27
          • 1970-01-01
          • 2012-11-09
          • 1970-01-01
          • 1970-01-01
          • 2015-12-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多