gpt4 book ai didi

java - 垃圾收集器与集合

转载 作者:搜寻专家 更新时间:2023-11-01 01:20:56 25 4
gpt4 key购买 nike

我已经阅读了一些关于 Java 中垃圾回收的文章,但我仍然无法确定明确清除垃圾回收是否被认为是一种好的做法......并且由于我找不到明确的答案,所以我决定在这里提问.

考虑这个例子:

List<String> list = new LinkedList<>();
// here we use the list, perhaps adding hundreds of items in it...
// ...and now the work is done, the list is not needed anymore
list.clear();
list = null;

从我在例如实现中看到的LinkedListHashSetclear() 方法基本上只是循环给定集合中的所有项目,设置其所有元素(如果 LinkedList 还引用了下一个和上一个元素)到 null

如果我做对了,将 list 设置为 null 只会从 list 中删除一个引用 - 考虑到它是对它的唯一引用,垃圾收集器最终会处理它。我只是不知道在这种情况下,垃圾收集器还需要多长时间才能处理列表的元素。

所以我的问题是 - 上面列出的示例代码的最后两行实际上是否有助于垃圾收集器更有效地工作(即更早地收集列表的元素)或者我会让我的应用程序忙于“不相关的任务” ?

最佳答案

最后两行没有帮助。

  • 一旦 list 变量超出范围*,如果这是对链表的最后引用,则该列表符合垃圾回收条件。立即将 list 设置为 null 不会增加任何值。

  • 一旦列表符合垃圾回收条件,那么如果列表包含对它们的唯一引用,则对其元素进行处理。不需要清除列表。

在大多数情况下,您可以相信垃圾收集器会完成它的工作,不需要“帮助”它。

* 迂腐地说,控制垃圾回收的不是范围,而是可达性。可达性不容易用一句话概括。参见 this Q&A以获得对这种区别的解释。


此规则的一个常见异常(exception)情况是,如果您的代码保留引用的时间比需要的时间长。典型的例子是听众。如果您向某个组件添加了一个监听器,并且稍后不再需要该监听器,则需要显式将其删除。如果不这样做,该监听器可以禁止对其自身及其引用的对象进行垃圾回收。

假设我像这样向按钮添加了一个监听器:

button.addListener(event -> label.setText("clicked!"));

然后标签被移除,但按钮仍然存在。

window.removeChild(label);

这是一个问题,因为按钮引用了监听器,而监听器引用了标签。即使标签在屏幕上不再可见,也无法对其进行垃圾回收。

现在是采取行动并站在 GC 一边的时候了。我需要在添加时记住监听器...

Listener listener = event -> label.setText("clicked!");
button.addListener(listener);

...这样我就可以在完成标签后将其删除:

window.removeChild(label);
button.removeListener(listener);

关于java - 垃圾收集器与集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32511624/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com