当ChangeListener被输入为lambda时,JavaFX中的addListener是否会被垃圾收集?

我意识到我的项目使用了很多 JavaFXChangeListeners来跟踪某些条件。

我很确定在使用 with 时侦听器不会被垃圾收集property.addListener(ChangeListener),但是如果我将我的侦听器置于 lambda 形式而不是首先声明它们,它们仍然不会被垃圾收集吗?

例子:

        field.focusedProperty().addListener((obs, oldVal, newVal) -> {
          // Do stuff
          }
        });

附带说明一下,当我关闭程序时,所有侦听器都会被清除还是继续存在?

回答

监听器会被垃圾收集吗?

只要注册到 observable 的侦听器注册到 observable 的侦听器,就不会被垃圾收集。当然,假设有对 observable 的强烈引用。这是因为 observable 对注册的每个侦听器都有一个强引用。事实上,如果您不小心,这可能是您的应用程序内存泄漏的原因。这就是为什么我们有:

弱听者

为了使您的应用程序更能抵抗内存泄漏,您可以使用WeakListener. 为您提供了五种公共实现:

  1. WeakInvalidationListener
  2. WeakChangeListener
  3. WeakListChangeListener
  4. WeakSetChangeListener
  5. WeakMapChangeListener

这些实现包装了它们相应的侦听器并将其保存在WeakReference. 这样 observable 只对弱侦听器有很强的引用,而不是“真正的”侦听器。这就是为什么你必须在需要时自己保持对“真实”侦听器的强引用,否则它会过早被垃圾收集。

例子

这是使用弱侦听器的示例:

import javafx.beans.value.ChangeListener;
import javafx.beans.value.WeakChangeListener;
import javafx.scene.Node;

public class Foo {
  
  // strong reference to "real" listener
  private final ChangeListener<Boolean> focusListener =
      (obs, oldVal, newVal) -> {
        // do something...
      };

  private final Node node;

  public Foo(Node node) {
    this.node = node;
    node.focusedProperty().addListener(new WeakChangeListener<>(focusListener));
  }
}

如果您需要能够随意删除弱侦听器,那么您还需要保留对它的引用。

何时使用弱监听器

当您不能保证不再需要时将删除侦听器时,您应该使用弱侦听器。如果侦听器捕获对其他对象的引用(例如Foo上面示例中的实例),这一点尤其重要。

如果 observable 和 listener 保证在相对相同的时间被垃圾收集,请不要使用弱侦听器。例如,如果Foo有一个属性并且将一个侦听器添加到该属性本身(例如this.someProperty().addListener((...) -> {...})),那么当Foo实例被垃圾回收时,该属性以及侦听器将被垃圾回收。

此外,如果出现以下情况,使用弱监听器可能会比它们的价值更费力:

  • 您的应用程序是微不足道的或相对短暂的。
  • 您的应用程序是相对静态的(即不会连续创建和丢弃您注册侦听器的对象)。

如果不确定,您总是可以走非弱路线开始,只有在您分析问题时才更改为弱听众。

事件处理程序

此处描述的所有内容都适用于EventHandlerWeakEventHandler。请注意,后者没有实现WeakListener.

Lambda 表达式

使用 lambda 表达式来实现侦听器(或处理程序)会改变什么吗?与此上下文没有任何关系。一个 lambda 表达式只是一个函数接口的实现。通过 lambda 表达式创建的实例与其他任何实例一样。

应用程序退出时会发生什么?

当该进程退出时,分配给该进程的所有内存都将释放回操作系统。这意味着所有对象都不再存在于内存中。

  • How garbage collection works is deceptively simple in theory (it's the implementation that's complex). Basically there's a graph of object references created by the application. This graph has one or more roots (e.g. thread objects). The garbage collector traverses the graph and every object it _cannot_ reach is eligible for garbage collection. So a listener will be garbage collected along with the observable if, and only if, there are no other strong references to the listener. That's the case in the "Don't bother..." paragraph above.

以上是当ChangeListener被输入为lambda时,JavaFX中的addListener是否会被垃圾收集?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>