我在运行一个java程序,它使用了很多向量。我担心我使用它们会导致垃圾收集器无法工作。我有很多这样的线程:
vec.addAll(<collection>);
以及其他执行以下操作的线程:
vec.remove(0);
我有打印输出,显示向量有时是空的,但我想知道,如果内存是真的释放。我需要担心吗?
bmvo0sr51#
如果向量中的对象在任何地方都没有被引用(由向量或任何其他代码引用),那么它们将由垃圾收集器自行收集。99.999%的时候垃圾收集器不需要你的帮助。但是,即使在垃圾收集器释放对象之后,它也可能不会将堆内存还给操作系统,因此您的进程可能会比它应该拥有的内存更多。另外,我对vector类的实现不是很熟悉(正如其他人所指出的,您应该真正使用 ArrayList 但是当你打电话的时候 .remove() 我不认为底层数组会向下调整大小。因此,如果将几千个对象填充到一个向量中,然后将它们全部删除,则可能仍会分配几千字节的空数组。这种情况下的解决办法是 vector.trimToSize() .
ArrayList
.remove()
vector.trimToSize()
waxmsbnn2#
不。只要相信标准库的实现者就行了。他们可能做得很好。如果您真的担心内存泄漏,请不时调用以下命令:
System.out.println("Total Memory"+Runtime.getRuntime().totalMemory()); System.out.println("Free Memory"+Runtime.getRuntime().freeMemory());
System.out.println("Total Memory"+Runtime.getRuntime().totalMemory());
System.out.println("Free Memory"+Runtime.getRuntime().freeMemory());
snz8szmq3#
不,你没有。如果向量为空,则它不会引用您曾经放置在其中的对象。如果你想知道是什么在占用内存,你可以找一个分析器,看看是什么在消耗内存。
kknvjkwl4#
jdk1.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;}
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;
}
如您所见,如果元素从向量中移除,向量将不会保留对它们的引用,因此不会妨碍它们的垃圾收集。但是,向量本身(以及支持它的潜在大数组)可能不会被回收。
v1l68za45#
如果没有对相关对象的引用,内存最终将被释放。看到你的向量变为空表示至少它们没有保留引用。如果对这些对象的引用没有其他内容,它们将被清除,但只有在垃圾收集器选择这样做时(这总是在内存耗尽之前)。
sshcrbum6#
(注意:显然,调用remove(0)只会从向量中移除第一个元素,而不会移除多个元素。)假设你 Vector 如果向量中的对象没有被其他地方引用,那么就不需要担心垃圾回收。但是,如果还有其他对对象的引用,那么它们就不可能被垃圾收集。为了验证这一点,我建议运行一个profiler(例如jprofiler)并定期“捕捉”存储在您数据库中的对象类型的对象计数 Vector ,然后监视此计数以查看它是否随时间增加。还有一条建议: Vector 已过时;您应该考虑改用linkedlist或arraylist,它们是线程不安全的等价物。如果你想让他们线程安全,你应该初始化他们使用 Collections.synchronizedList(new ArrayList());
Vector
Collections.synchronizedList(new ArrayList());
6条答案
按热度按时间bmvo0sr51#
如果向量中的对象在任何地方都没有被引用(由向量或任何其他代码引用),那么它们将由垃圾收集器自行收集。99.999%的时候垃圾收集器不需要你的帮助。
但是,即使在垃圾收集器释放对象之后,它也可能不会将堆内存还给操作系统,因此您的进程可能会比它应该拥有的内存更多。
另外,我对vector类的实现不是很熟悉(正如其他人所指出的,您应该真正使用
ArrayList
但是当你打电话的时候.remove()
我不认为底层数组会向下调整大小。因此,如果将几千个对象填充到一个向量中,然后将它们全部删除,则可能仍会分配几千字节的空数组。这种情况下的解决办法是vector.trimToSize()
.waxmsbnn2#
不。
只要相信标准库的实现者就行了。他们可能做得很好。
如果您真的担心内存泄漏,请不时调用以下命令:
snz8szmq3#
不,你没有。如果向量为空,则它不会引用您曾经放置在其中的对象。如果你想知道是什么在占用内存,你可以找一个分析器,看看是什么在消耗内存。
kknvjkwl4#
jdk1.6中java.util.vector.remove(int)的实现是:
如您所见,如果元素从向量中移除,向量将不会保留对它们的引用,因此不会妨碍它们的垃圾收集。
但是,向量本身(以及支持它的潜在大数组)可能不会被回收。
v1l68za45#
如果没有对相关对象的引用,内存最终将被释放。看到你的向量变为空表示至少它们没有保留引用。如果对这些对象的引用没有其他内容,它们将被清除,但只有在垃圾收集器选择这样做时(这总是在内存耗尽之前)。
sshcrbum6#
(注意:显然,调用remove(0)只会从向量中移除第一个元素,而不会移除多个元素。)
假设你
Vector
如果向量中的对象没有被其他地方引用,那么就不需要担心垃圾回收。但是,如果还有其他对对象的引用,那么它们就不可能被垃圾收集。为了验证这一点,我建议运行一个profiler(例如jprofiler)并定期“捕捉”存储在您数据库中的对象类型的对象计数
Vector
,然后监视此计数以查看它是否随时间增加。还有一条建议:
Vector
已过时;您应该考虑改用linkedlist或arraylist,它们是线程不安全的等价物。如果你想让他们线程安全,你应该初始化他们使用Collections.synchronizedList(new ArrayList());