Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/361.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 向量和垃圾收集器_Java_Garbage Collection_Vector - Fatal编程技术网

Java 向量和垃圾收集器

Java 向量和垃圾收集器,java,garbage-collection,vector,Java,Garbage Collection,Vector,我正在运行一个使用许多向量的java程序。我担心我使用它们会导致垃圾收集器无法工作 我有许多这样做的线程: vec.addAll(<collection>); vec.remove(0); 我有打印输出,显示向量有时是空的,但我想知道内存是否真的被释放了 我需要担心吗?如果没有对相关对象的引用,内存最终将被释放。看到向量变为空表示它们至少没有保留引用。如果对这些对象的引用没有其他内容,它们将被清除,但只有当垃圾收集器选择这样做时(这总是在内存耗尽之前)。不,您没有。如果向量为空,

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

我有许多这样做的线程:

vec.addAll(<collection>);
vec.remove(0);
我有打印输出,显示向量有时是空的,但我想知道内存是否真的被释放了


我需要担心吗?

如果没有对相关对象的引用,内存最终将被释放。看到向量变为空表示它们至少没有保留引用。如果对这些对象的引用没有其他内容,它们将被清除,但只有当垃圾收集器选择这样做时(这总是在内存耗尽之前)。

不,您没有。如果向量为空,则它不会引用您放置在其中的对象。如果您想知道哪些内容占用了内存,可以使用探查器查看哪些内容占用了内存。

只要相信标准库的实现者就行了。他们可能做得很好

如果您真的担心内存泄漏,请随时调用此选项:

 System.out.println("Total Memory"+Runtime.getRuntime().totalMemory());    
 System.out.println("Free Memory"+Runtime.getRuntime().freeMemory());
(注意:显然,调用remove(0)只会从向量中删除第一个元素,而不会删除多个元素。)

假设您的
向量
为空,那么如果向量中的对象未在其他地方引用,则无需担心垃圾收集。但是,如果仍然存在对对象的其他引用,则无法对其进行垃圾收集

为了验证这一点,我建议运行一个探查器(例如JProfiler),并定期“捕捉”存储在
向量中的对象类型的对象计数,然后监视此计数是否随时间增加


另一条建议:
Vector
已过时;您应该考虑使用LIKEDLIST或ARAYLIST,这是线程不安全的等价物。如果您希望使它们成为线程安全的,您应该使用Collections.synchronizedList(new ArrayList())初始化它们

如果向量中的对象没有被任何地方引用(由向量或任何其他代码引用),那么它们将由垃圾收集器自行收集。99.999%的时间垃圾收集器不需要您的帮助

但是,即使在垃圾收集器释放对象之后,它也可能不会将堆内存返回给操作系统,因此您的进程可能会比它应该拥有的内存更多


此外,我不太熟悉Vector类的实现(正如其他人所指出的,实际上应该使用
ArrayList
),但是当调用
.remove()
时,我认为底层数组的大小永远不会向下调整。因此,如果您将数千个对象填充到一个向量中,然后将它们全部删除,它可能仍会分配数千字节的空数组。本例中的解决方案是调用。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;
}
如您所见,如果从向量中删除元素,向量将不会保留对它们的引用,因此不会妨碍它们的垃圾收集


但是,向量本身(以及支持它的潜在大数组)可能无法回收。

不,Java有几种垃圾收集器,但据我所知,没有一种可以使用引用计数;如果对象图中存在循环,引用计数策略将失败,因为引用计数永远不会达到零。确定。我关于引用计数的旁白被删除了。您现在可以给我一些提点:-)+1:关于底层数组没有自动调整大小的观点很好。ArrayList具有相同的功能。