7

我想在 HashSet 中处理一些新数据,而不需要任何旧数据或旧 HashSet 对象。旧的 HashSet 对象不在其他地方引用。

是简单地hashset = new HashSet<String>()让 JVM 释放旧 HashSet 对象的内存更好,还是应该调用hashSet.clear()并重用相同的 HashSet?

根据 openJDK, hashSet.clear() 是:

public void clear() {
    map.clear();
}

和 map.clear() :

public void clear() {
     modCount++;
     Entry[] tab = table;
     for (int i = 0; i < tab.length; i++)
         tab[i] = null;
     size = 0;
 }

既然map.clear()会迭代所有的entry,那么hashSet很大的时候会不会很耗时?在这种情况下推荐哪一个,构造方法还是 clear() 方法?

4

7 回答 7

6

简单的不再引用您HashSet的,让垃圾收集器完成工作。

在取消引用之前清除HashSet它不会更快地释放内存。

于 2013-08-29T11:32:05.923 回答
4

清除 HashSet 是不必要的 - 只需删除对 HashSet 的所有引用(如果您编写 HashSet 会发生这种情况hashset = new HashSet<>();,假设在其他任何地方都没有引用旧的 HashSet),然后垃圾收集器将完成剩下的工作。

另请注意,假设您需要一个相同大小的新 HashSet,调用hashset.clear()比简单地创建一个具有适当容量的新 HashSet 需要更多时间

于 2013-08-29T11:31:51.843 回答
3

我认为这里有一个误解。您不会手动释放 java 中的内存。即使你调用System.gc();它也不能保证 GC 会在那个时候运行。

至于你的问题:我认为你应该在尽可能小的范围内使用你的引用,当代码离开你的范围时Set,对它的引用就会被删除,GC 会收集它。

clear();如果您对 : 有进一步的工作,我认为建议您使用Set:例如,如果您处理了其中的数据并且准备将一些其他数据放入其中。

在实践中,我几乎从来没有看到显式(如果你想要显式取消引用,因为没有任何意义mySet = null; ,这是你应该使用mySet = new HashSet<>()的)语句,因为使用适当的范围更容易且不那么麻烦。

于 2013-08-29T11:56:15.653 回答
2

在java中无法释放内存。你所能做的就是让虚拟机知道它可以在它想要的时候释放它。当事情超出范围时,这通常会发生。一般来说,不用担心也没关系。如果您已经分析了您的应用程序并且发现了内存泄漏,那么您可以尝试找到它。

绝对不要制作新的 HashSet。clear() 将从 HashSet 中删除所有项目,但在超出范围之前仍不会被收集。

于 2013-08-29T11:31:37.190 回答
0

如果您没有对对象的任何引用,垃圾收集器会自动删除它们。您无需手动执行此操作。

于 2013-08-29T11:32:58.367 回答
0

这取决于,如果你有非常小的地图,那么在这种情况下,清理会比生成对象更好。

而且,如果您的地图中有很多项目,那么甚至不值得清除它。就像您看到该clear()方法的实现一样,它会遍历所有元素。在这种情况下,创建新对象会便宜一些。

但通常最好让垃圾收集器负责清理事物,然后您继续创建新对象,而垃圾收集器将清除剩余的引用。

但根据经验,应该尝试限制正在创建的对象的数量。正如我所说,这取决于。

于 2013-08-29T11:33:53.353 回答
0

内存管理由 JVM 自己完成。因此,即使您手动释放内存,无论如何都会自动收集垃圾。

垃圾收集器减少了有关内存管理的编码工作。

于 2013-08-29T11:45:42.027 回答