矢量和垃圾收集器

时间:2009-11-03 22:29:42

标签: java garbage-collection vector

我正在运行一个使用很多向量的java程序。我担心使用它们会导致垃圾收集器无法正常工作。

我有很多线程可以:

vec.addAll(<collection>);

和其他线程:

vec.remove(0);

我有打印输出显示向量是空的,但我想知道内存是否实际被释放。

我需要担心吗?

6 个答案:

答案 0 :(得分:5)

如果Vector中的对象没有被引用(通过Vector或任何其他代码),那么它们将由垃圾收集器自行决定收集。垃圾收集者99.999%的时间不需要你的帮助。

但是,即使在垃圾回收器释放了对象之后,它也可能无法将堆内存返回给操作系统,因此您的进程可能会占用更多内存。

另外,我对Vector类的实现非常熟悉(正如其他人指出的那样,你应该真的使用ArrayList代替),但是当你打电话给.remove()我不知道t认为底层数组的大小是向下调整的。因此,如果您将数千个对象填充到Vector中然后将它们全部删除,则可能仍会分配几千个字节的空数组。在这种情况下,解决方案是调用vector.trimToSize()

答案 1 :(得分:4)

如果没有对相关对象的引用,最终将释放内存。看到你的向量变空表明至少他们没有坚持参考。如果没有其他引用这些对象的东西,它们将被清理,但只有当垃圾收集器选择这样做时(总是在你的内存耗尽之前)。

答案 2 :(得分:1)

(警告:显然调用remove(0)只会删除Vector中的第一个元素,而不是多个元素。)

假设您的Vector为空,那么如果向量中的对象未在其他地方引用,则无需担心垃圾回收。但是,如果还有其他对象的引用,则无法对它们进行垃圾回收。

为了验证这一点,我建议运行一个分析器(例如JProfiler)并定期“捕捉”Vector中存储的对象类型的对象计数,然后监视此计数以查看它是否存在随着时间的推移而增加。

另一条建议:Vector已过时;您应该考虑使用LinkedList或ArrayList,它们是线程不安全的等价物。如果您希望使它们具有线程安全性,则应使用Collections.synchronizedList(new ArrayList());

对其进行初始化

答案 3 :(得分:0)

不,你没有。如果向量为空,则不会引用您曾经放入的对象。如果你想知道什么是内存,你可以得到一个分析器,看看消耗内存的是什么。

答案 4 :(得分:0)

没有

只需信任标准库的实现者。他们可能做得很好。

如果您真的担心内存泄漏,请不时致电:

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

答案 5 :(得分:0)

JDK 1.6中java.util.Vector.remove(int)的实现是:

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;
}

如您所见,如果从向量中删除元素,向量将不会保留对它们的引用,因此不会妨碍它们的垃圾回收。

但是,矢量本身(以及支持它的潜在大型阵列)可能无法回收。