创建一个新的HashSet还是在调用hashSet.clear()之后重复使用更好?

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()会迭代所有条目,因此当hashSet很大时,这会耗费时间吗? 在这种情况下,建议使用哪种方法,构造函数方法还是clear()方法?


4
只用 hashSet = null; 怎么样? - Aniket Thakur
@AniketThakur 嗯,实际上,我需要一个新的哈希集。如果我之后要新建一个哈希集,是否也有必要将哈希集分配为null? - wings
@wings 不要将其设置为null。如果你需要一个新的HashSet,就创建一个新的。或者,更好的做法可能是使用一个不同的变量,因为新的HashSet很可能会用于其他用途。 - Eric Stein
7个回答

6

简单地不再引用你的HashSet,让垃圾回收器来完成工作。

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


4

2
你的解决方案是分配更多的内存来释放内存?这没有任何意义。对象将在超出范围时清除。你只是用另一个映射替换了一个映射。 - Eric Stein
@EricStein 我假设 OP 需要一个新的 HashSet - 否则确实没有意义。我已经澄清了这一点。 - assylias
@assylias 谢谢,这真的很有帮助。你能告诉我,我需要将旧的hashSet分配为null吗?这有助于“通知”GC释放内存吗?如果没有用将hashSet中的每个条目分配为null,那么为什么jdk本身要提供一个像clear()这样的函数,而不是简单地新建一个hashSet呢?这是为了内存容量的原因吗? - wings
2
@wings 如果你将任何变量赋值为null,内存不会被释放得更快。只有当内存满了时,垃圾回收器才会释放内存。 - Uwe Plonus
1
@wings,你不能替换一个对象本身。因此,集合只有将所有引用设置为“null”的可能性。从外部,你可以简单地创建一个新对象。 - Uwe Plonus

3
我认为这里存在一个误解。在Java中,您不需要手动释放内存。即使您调用了System.gc();,也不能保证垃圾回收会在那个时刻运行。
至于您的问题:我认为您应该在最小可能的范围内使用引用,在代码离开您的Set范围时,对它的引用将被简单地删除,垃圾回收器将收集它。
如果您需要进一步处理Set中的数据并准备将其他数据放入其中,则建议使用clear();
在实践中,我几乎从未看到显式的mySet = null;语句(如果您想要明确取消引用,这就是您应该使用的方式,因为mySet = new HashSet<>()没有任何意义),因为只需使用适当的范围更容易和不那么麻烦。

2

在Java中无法释放内存。你所能做的就是让虚拟机知道如果需要时可以释放它。当对象超出范围时,通常会发生这种情况。一般来说,不必担心这个问题。如果你对应用程序进行了分析并发现了内存泄漏,那么你可以尝试找到它。

绝对不要创建新的HashSet。clear()方法将从HashSet中删除所有项,但只有在超出作用域之后才会被回收。


谢谢。但是我不太明白你所说的“绝对不要创建一个新的HashSet”。你能再解释一下吗? - wings
@wings 如果你需要一个新的对象,就创建一个新的对象。不要只是创建一个来删除旧对象的引用。 - Eric Stein

0

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


0

这要看情况,如果你的地图非常小,那么清除比生成对象更好。

如果你的地图中有很多物品,那么清除它甚至不值得。因为如果你查看clear()方法的实现,它会遍历所有元素。在这种情况下,创建新对象会更便宜一些。

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

但作为一个经验法则,应该尽量限制创建对象的数量。就像我说的,这取决于具体情况。


0
内存管理由JVM自身完成。因此,即使您手动释放内存或不释放内存,它也会被自动垃圾回收。
垃圾回收器减少了关于内存管理的编码工作量。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接