垃圾收集器与集合 [英] Garbage collector vs. collections

查看:87
本文介绍了垃圾收集器与集合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经阅读了几篇关于Java中垃圾收集的文章,但我仍然无法确定明确清理集合是否被认为是一种好的做法......并且由于找不到明确的答案,我决定在此处询问它。

考虑这个例子:

  List< String> list = new LinkedList<>(); 
//这里我们使用列表,可能会在其中添加数百个项目...
// ...现在工作完成了,列表不再需要
列表。明确();
list = null;

从我在例如 LinkedList HashSet clear()方法基本上只是循环给定集合中的所有项目,将其所有元素(在 LinkedList 也引用下一个元素和前一个元素的情况下)设置为 null

如果我把它正确的话,把 list 设置为 null 只是从 list 删除一个引用 - 考虑到它是唯一的引用,垃圾收集器最终会处理它。我只是不知道需要多长时间,直到列表的元素在这种情况下由垃圾收集器处理。



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

解决方案

最后两行没有帮助。




  • c $ c> list 变量超出了作用域 * ,如果这是链接列表的最后一个引用,那么该列表就成为垃圾收集的条件。立即提前设置 list null 不会增加任何值。


  • 一旦列表成为垃圾收集的资格,那么如果列表只包含对它们的引用,则执行它的元素。清除列表是不必要的。




大多数情况下,您可以信任垃圾回收器来完成它的工作,需要帮助它。



* 迂回地说,它不是控制垃圾收集的 ,但可达性。可达性不容易用一句话来总结。请参阅本Q& A 以了解这种区别的解释。




这个规则的一个常见例外是,如果你有代码将保留引用比他们需要的更长。这个典型的例子是听众。如果您向某个组件添加侦听器,并且稍后不再需要该侦听器,则需要明确地将其删除。如果你不这样做,那么这个监听器就可以禁止它自己和它引用的对象的垃圾回收。



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

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

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

  window.removeChild(label); 

这是一个问题,因为按钮有一个对侦听器的引用,并且侦听器引用了标签。即使屏幕上不再显示标签,也无法收集标签。



现在是采取行动并取得GC良好表现的时候了。当我添加它时,我需要记住听众...

label.setText( 点击!);
button.addListener(listener);

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

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


I have read few posts about garbage collection in Java, but still I cannot decide whether clearing a collection explicitly is considered a good practice or not... and since I could not find a clear answer, I decided to ask it here.

Consider this example:

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;

From what I saw in implementations of e.g. LinkedList or HashSet, the clear() method basically just loops all the items in the given collection, setting all its elements (in case of LinkedList also references to next and previous elements) to null

If I got it right, setting the list to null just removes one reference from list - considering it was the only reference to it, the garbage collector will eventually take care of it. I just don't know how long would it take until also the list's elements are processed by garbage collector in this case.

So my question is - do the last two lines of the above listed example code actually help the garbage collector to work more efficiently (i.e. to collect the list's elements earlier) or would I just make my application busy with "irrelevant tasks"?

解决方案

The last two lines do not help.

  • Once the list variable goes out of scope*, if that's the last reference to the linked list then the list becomes eligible for garbage collection. Setting list to null immediately beforehand adds no value.

  • Once the list becomes eligible for garbage collection, so to do its elements if the list holds the only references to them. Clearing the list is unnecessary.

For the most part you can trust the garbage collector to do its job and do not need to "help" it.

* Pedantically speaking, it's not scope that controls garbage collection, but reachability. Reachability isn't easy to sum up in one sentence. See this Q&A for an explanation of this distinction.


One common exception to this rule is if you have code that will retain references longer than they're needed. The canonical example of this is with listeners. If you add a listener to some component, and later on that listener is no longer needed, you need to explicitly remove it. If you don't, that listener can inhibit garbage collection of both itself and of the objects it has references to.

Let's say I added a listener to a button like so:

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

Then later on the label is removed, but the button remains.

window.removeChild(label);

This is a problem because the button has a reference to the listener and the listener has a reference to the label. The label can't be garbage collected even though it's no longer visible on screen.

This is a time to take action and get on the GC's good side. I need to remember the listener when I add it...

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

...so that I can remove it when I'm done with the label:

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

这篇关于垃圾收集器与集合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆