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:
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) {
.
开发者_如何学JAVA .
.
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.
However, as I said, the number of java.util.LinkedList$Entry objects seems to be steadily increasing.
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?
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).
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
.
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.
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.
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).
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.
精彩评论