我正在运行一个使用很多向量的java程序。我担心使用它们会导致垃圾收集器无法正常工作。
我有很多线程可以:
vec.addAll(<collection>);
和其他线程:
vec.remove(0);
我有打印输出显示向量是空的,但我想知道内存是否实际被释放。
我需要担心吗?
答案 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;
}
如您所见,如果从向量中删除元素,向量将不会保留对它们的引用,因此不会妨碍它们的垃圾回收。
但是,矢量本身(以及支持它的潜在大型阵列)可能无法回收。