释放java.util.LinkedList $条目内存

时间:2021-08-05 04:21:25

I have an application in which the number of java.util.LinkedList$Entry objects seems to be steadily increasing. This application contains a method that contains the following code:

我有一个应用程序,其中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);
                      .
                      .
                      .
    }

The method that contains this code is called many, many times. And, of course, each time the method returns, the List objects go out of scope, and, presumably, are available for garbage collection.

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

However, as I said, the number of java.util.LinkedList$Entry objects seems to be steadily increasing.

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

Have I created a memory leak here? Should I call some method on the List objects at the end of the method so that the LinkedList$Entry objects can be garbage collected?

我在这里创建了内存泄漏吗?我应该在方法末尾的List对象上调用一些方法,以便可以对LinkedList $ Entry对象进行垃圾回收吗?

3 个解决方案

#1


4  

No, you don't need to do any explicit de-initialization for the objects to be claimable.

不,您不需要对要声明的对象进行任何显式的去初始化。

Your best bet is to find out why the elements are not garbage collected. To do this, use your prefered memory profiler, take a snapshot and try to trace some of those elements path to the nearest GC route (personally I'd suggest VisualVM, since it's relatively simple to use and still powerful enough for many things).

最好的办法是找出为什么元素不是垃圾收集的。要做到这一点,使用您喜欢的内存分析器,拍摄快照并尝试跟踪其中一些元素路径到最近的GC路径(我个人建议使用VisualVM,因为它使用起来相对简单,而且对于很多东西来说仍然足够强大)。

Also: in your sample you use ArrayList as your List implementation. That implementation does not use Entry objects. So you need to check where in your code you use a LinkedList.

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

#2


0  

Did you check whether the garbage collector actually ran? Under normal circumstances the JVM decides to run the gc at regular intervals or when memory is scarce.

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

And as Joachim Sauer said, there might be some dangling reference from an active thread to your lists. So if the gc ran but did not collect at least some of those objects (it might sometimes not collect all objects that are eligible for gc, so that's not generally a problem) you should check where the references are.

正如Joachim Sauer所说,从活动主题到你的列表可能会有一些悬空引用。因此,如果gc运行但至少没有收集其中一些对象(它有时可能不会收集所有符合gc条件的对象,因此通常不会出现问题),您应该检查引用的位置。

We once had a problem with database connection entries that were closed but not released and thus held tons of data in some maps. Getting rid of the references to those connections helped in that case, but it was only obvious, when we imployed a memory tracing tool (JProbe in our case).

我们曾经遇到过关闭但未发布的数据库连接条目的问题,因此在一些地图中保存了大量数据。在这种情况下,摆脱对这些连接的引用有所帮助,但是当我们使用内存跟踪工具(在我们的例子中为JProbe)时,这是显而易见的。

#3


0  

It looks like no memory leaks here. It depends on how you use the result of this. In general, garbage collector will collect all of them. From the other hand it will be better for memoty usage and hadling when it will be only one list and the data will be wrapped into structure contains these fields. When it will be adding the 17-th item - new blok will be allocated in memory and previous items will be moved to the new block of memory. So it is better to make it only once instead 4 time. And the last notice is that it is better to use constructor where you can provide count of items. It will allocate appropriative block of memory. It will avoid possible reallocations in when you will fill the collection.

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

#1


4  

No, you don't need to do any explicit de-initialization for the objects to be claimable.

不,您不需要对要声明的对象进行任何显式的去初始化。

Your best bet is to find out why the elements are not garbage collected. To do this, use your prefered memory profiler, take a snapshot and try to trace some of those elements path to the nearest GC route (personally I'd suggest VisualVM, since it's relatively simple to use and still powerful enough for many things).

最好的办法是找出为什么元素不是垃圾收集的。要做到这一点,使用您喜欢的内存分析器,拍摄快照并尝试跟踪其中一些元素路径到最近的GC路径(我个人建议使用VisualVM,因为它使用起来相对简单,而且对于很多东西来说仍然足够强大)。

Also: in your sample you use ArrayList as your List implementation. That implementation does not use Entry objects. So you need to check where in your code you use a LinkedList.

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

#2


0  

Did you check whether the garbage collector actually ran? Under normal circumstances the JVM decides to run the gc at regular intervals or when memory is scarce.

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

And as Joachim Sauer said, there might be some dangling reference from an active thread to your lists. So if the gc ran but did not collect at least some of those objects (it might sometimes not collect all objects that are eligible for gc, so that's not generally a problem) you should check where the references are.

正如Joachim Sauer所说,从活动主题到你的列表可能会有一些悬空引用。因此,如果gc运行但至少没有收集其中一些对象(它有时可能不会收集所有符合gc条件的对象,因此通常不会出现问题),您应该检查引用的位置。

We once had a problem with database connection entries that were closed but not released and thus held tons of data in some maps. Getting rid of the references to those connections helped in that case, but it was only obvious, when we imployed a memory tracing tool (JProbe in our case).

我们曾经遇到过关闭但未发布的数据库连接条目的问题,因此在一些地图中保存了大量数据。在这种情况下,摆脱对这些连接的引用有所帮助,但是当我们使用内存跟踪工具(在我们的例子中为JProbe)时,这是显而易见的。

#3


0  

It looks like no memory leaks here. It depends on how you use the result of this. In general, garbage collector will collect all of them. From the other hand it will be better for memoty usage and hadling when it will be only one list and the data will be wrapped into structure contains these fields. When it will be adding the 17-th item - new blok will be allocated in memory and previous items will be moved to the new block of memory. So it is better to make it only once instead 4 time. And the last notice is that it is better to use constructor where you can provide count of items. It will allocate appropriative block of memory. It will avoid possible reallocations in when you will fill the collection.

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