简体   繁体   English

释放java.util.LinkedList $ Entry内存

[英]Releasing java.util.LinkedList$Entry memory

I have an application in which the number of java.util.LinkedList$Entry objects seems to be steadily increasing. 我有一个应用程序,其中java.util.LinkedList $ Entry对象的数量似乎正在稳步增加。 This application contains a method that contains the following code: 此应用程序包含一个包含以下代码的方法:

    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对象吗?

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. 另外:在示例中,您将ArrayList用作List实现。 That implementation does not use Entry objects. 这实现使用Entry对象。 So you need to check where in your code you use a LinkedList . 因此,您需要检查代码中使用LinkedList

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。

And as Joachim Sauer said, there might be some dangling reference from an active thread to your lists. 正如Joachim Sauer所说,从活动线程到列表的引用可能有些悬而未决。 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. 因此,如果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)时,这才很明显。

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. 当它将添加第17个项目时-新的块将分配到内存中,而以前的项目将被移到新的内存块中。 So it is better to make it only once instead 4 time. 因此最好只设置一次而不是4次。 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. 它将在您填充集合时避免可能的重新分配。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM