views:

234

answers:

6

I'm running a java program that uses many vectors. I'm afraid my use of them is causing the garbage collector not to work.

I have many threads that do:

vec.addAll(<collection>);

and other threads that do:

vec.remove(0);

I have printouts that show the vector is empty from time to time but I was wondering if the memory is actually freed.

Do I need to worry?

+3  A: 

The memory will eventually be freed if there are no references to the objects in question. Seeing your vectors become empty indicates that at least they are not holding on to references. If there is nothing else with references to those objects, they will be cleaned up, but only when the garbage collector chooses to do so (which is always before you run out of memory).

SingleShot
No, Java has several choices of garbage collectors, but none that I know of use reference counting.
Daniel Pryden
Daniel is correct; a reference counting strategy would fail if there were cycles in the object graph as the reference count would never reach zero.
Adamski
OK. My side comment about reference counting was removed. You may now give me some upticks :-)
SingleShot
Well I'll remove my downvote :-)
Adamski
A: 

No, you don't. If the vector is empty it is not referencing objects you once put in there. If you want to know what is holding on to memory, you can get a profiler and look at what is consuming the memory.

Yishai
A: 

No.

Just trust the implementors of the standard library. They probably have done a good job.

If you really worry about memory leaks, call this from time to time :

 System.out.println("Total Memory"+Runtime.getRuntime().totalMemory());    
 System.out.println("Free Memory"+Runtime.getRuntime().freeMemory());
Gyom
+1  A: 

(Caveat: Obviously calling remove(0) will only remove the first element from the Vector, not multiple elements.)

Assuming your Vector is empty then you do not need to worry about garbage collection if the objects in your vector are not being referenced elsewhere. However, if there are still other references to the objects then there is no way they can be garbage collected.

To verify this, I'd recommend running a profiler (e.g. JProfiler) and periodically "snapping" the object count for the type of object being stored in your Vector, and then monitor this count to see if it increased over time.

One other piece of advice: Vector is obsolete; You should consider using LinkedList or ArrayList instead, which are thread-unsafe equivalents. If you wish to make them thread-safe you should initialise them using Collections.synchronizedList(new ArrayList());

Adamski
+4  A: 

If the objects in your Vectors are not referenced anywhere (by the Vector or by any other code), then they will get collected at the garbage collector's discretion. 99.999% of the time the garbage collector won't need your help with this.

However, even after the garbage collector frees the objects, it may not give heap memory back to the operating system, so your process may appear to hold more memory than it should.

Additionally, I'm very not familiar with the implementation of the Vector class (as others have pointed out, you should really be using ArrayList instead), but when you call .remove() I don't think the underlying array is ever resized downward. So if you stuff several thousand objects into a Vector and then delete them all, it will probably still have several thousand bytes of empty array allocated. The solution in this case is to call vector.trimToSize().

Daniel Pryden
+1: Good point about the underlying array not resizing automatically. ArrayList has the same feature.
Adamski
A: 

The implementation of java.util.Vector.remove(int) from JDK 1.6 is:

public synchronized E remove(int index) {
    modCount++;
    if (index >= elementCount)
        throw new ArrayIndexOutOfBoundsException(index);
    Object oldValue = elementData[index];

    int numMoved = elementCount - index - 1;
    if (numMoved > 0)
        System.arraycopy(elementData, index+1, elementData, index, numMoved);
    elementData[--elementCount] = null; // Let gc do its work

    return (E)oldValue;
}

As you can see, if elements are removed from the vector, the vector will not keep a reference to to them, and hence not impede their garbage collection.

However, the vector itself (and the potentially large array backing it) might not be reclaimed.

meriton