【问题标题】:Releasing java.util.LinkedList$Entry memory释放 java.util.LinkedList$Entry 内存
【发布时间】:2023-03-28 03:35:02
【问题描述】:

我有一个应用程序,其中 java.util.LinkedList$Entry 对象的数量似乎在稳步增加。此应用程序包含一个包含以下代码的方法:

    final List<Boolean> correctnessList = new ArrayList<Boolean>();
    final List<Double> discriminationList = new ArrayList<Double>();
    final List<Double> difficultyList = new ArrayList<Double>();
    final List<Double> guessingList = new ArrayList<Double>();
                 .
                 .
                 .
    for (ItemData datum : candidateItemData) {
                      .
                      .
                      .
        correctnessList.add(datum.isCorrect);
        discriminationList.add(iRTParameter.discrimination);
        difficultyList.add(iRTParameter.difficulty);
        guessingList.add(iRTParameter.guessing);
                      .
                      .
                      .
    }

包含此代码的方法被多次调用。当然,每次方法返回时,List 对象都会超出范围,并且可能可以用于垃圾回收。

但是,正如我所说,java.util.LinkedList$Entry 对象的数量似乎在稳步增加。

我是否在这里造成了内存泄漏?我是否应该在方法末尾调用 List 对象的某些方法,以便可以对 LinkedList$Entry 对象进行垃圾回收?

【问题讨论】:

  • 在这段代码中,您使用的是ArrayLists,而不是LinkedLists。您在此处发布时会出错吗?
  • 你在这里使用的是 ArrayLists,而不是 LinkedList。
  • 您有可能查看了错误的代码块。应该有LinkedLists 填充而不是ArrayLists 以​​增加LinkedLiset$Entrys 的数量。为什么你认为这个代码块是问题之一?
  • 不,我没有出错。我认为可能错误的代码包含 ArrayLists。内存问题出在 LinkedLists 上。也许我对真正的问题在哪里得出了错误的结论。

标签: java list memory memory-management memory-leaks


【解决方案1】:

不,您不需要为可声明的对象执行任何显式取消初始化。

最好的办法是找出为什么元素没有被垃圾回收。为此,请使用您喜欢的内存分析器,拍摄快照并尝试跟踪其中一些元素路径到最近的 GC 路径(我个人建议使用 VisualVM,因为它使用起来相对简单,并且对于许多事情仍然足够强大)。

另外:在您的示例中,您使用 ArrayList 作为您的 List 实现。该实现使用Entry 对象。因此,您需要检查您在代码中使用LinkedList 的位置。

【讨论】:

    【解决方案2】:

    你检查垃圾收集器是否真的运行了吗?在正常情况下,JVM 会决定定期运行 gc 或在内存不足时运行。

    正如 Joachim Sauer 所说,活动线程中可能有一些悬空引用指向您的列表。因此,如果 gc 运行但至少没有收集其中一些对象(它有时可能无法收集所有符合 gc 条件的对象,因此这通常不是问题),您应该检查引用的位置。

    我们曾经遇到过关闭但未释放的数据库连接条目的问题,因此在某些地图中保存了大量数据。在这种情况下,摆脱对这些连接的引用会有所帮助,但只有在我们使用内存跟踪工具(在我们的例子中为 JProbe)时才很明显。

    【讨论】:

    • 我在拍摄每个内存快照之前运行垃圾收集器。
    • 您的垃圾收集器和内存是如何配置的?请注意,只有在该空间被填满时,才会收集驻留在旧代空间中的对象。如果您的 eden 空间较小或这些调用正在处理大量数据,则列表可能会很快进入旧 gen 空间。
    【解决方案3】:

    这里看起来没有内存泄漏。这取决于您如何使用此结果。一般来说,垃圾收集器会收集所有这些。 另一方面,当它只有一个列表并且数据将被包装到包含这些字段的结构中时,它对于 memoty 的使用和 hadling 会更好。当它将添加第 17 项时 - 新块将被分配到内存中,之前的项将被移动到新的内存块中。所以最好只做一次而不是4次。 最后要注意的是,最好使用可以提供项目计数的构造函数。它将分配适当的内存块。它将避免在您填充集合时可能的重新分配。

    【讨论】:

      猜你喜欢
      • 2011-05-10
      • 1970-01-01
      • 1970-01-01
      • 2013-12-23
      • 2013-12-05
      • 2015-04-22
      • 2011-01-17
      • 2021-12-23
      • 2017-06-29
      相关资源
      最近更新 更多