jav*_*ons 1 java memory garbage-collection javafx listener
我意识到我的项目使用了很多 JavaFXChangeListeners来跟踪某些条件。
我很确定在使用 with 时侦听器不会被垃圾收集property.addListener(ChangeListener),但是如果我将我的侦听器置于 lambda 形式而不是首先声明它们,它们仍然不会被垃圾收集吗?
例子:
field.focusedProperty().addListener((obs, oldVal, newVal) -> {
// Do stuff
}
});
Run Code Online (Sandbox Code Playgroud)
附带说明一下,当我关闭程序时,所有侦听器都会被清除还是继续存在?
只要注册到 observable 的侦听器注册到 observable 的侦听器,就不会被垃圾收集。当然,假设有对 observable 的强烈引用。这是因为 observable 对注册的每个侦听器都有一个强引用。事实上,如果您不小心,这可能是您的应用程序内存泄漏的原因。这就是为什么我们有:
为了使您的应用程序更能抵抗内存泄漏,您可以使用WeakListener. 为您提供了五种公共实现:
WeakInvalidationListenerWeakChangeListenerWeakListChangeListenerWeakSetChangeListenerWeakMapChangeListener这些实现包装了它们相应的侦听器并将其保存在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));
}
}
Run Code Online (Sandbox Code Playgroud)
如果您需要能够随意删除弱侦听器,那么您还需要保留对它的引用。
当您不能保证不再需要时将删除侦听器时,您应该使用弱侦听器。如果侦听器捕获对其他对象的引用(例如Foo上面示例中的实例),这一点尤其重要。
如果 observable 和 listener 保证在相对相同的时间被垃圾收集,请不要使用弱侦听器。例如,如果Foo有一个属性并且将一个侦听器添加到该属性本身(例如this.someProperty().addListener((...) -> {...})),那么当Foo实例被垃圾回收时,该属性以及侦听器将被垃圾回收。
此外,如果出现以下情况,使用弱监听器可能会比它们的价值更费力:
如果不确定,您总是可以走非弱路线开始,只有在您分析问题时才更改为弱听众。
此处描述的所有内容都适用于EventHandler和WeakEventHandler。请注意,后者没有实现WeakListener.
使用 lambda 表达式来实现侦听器(或处理程序)会改变什么吗?与此上下文没有任何关系。一个 lambda 表达式只是一个函数接口的实现。通过 lambda 表达式创建的实例与其他任何实例一样。
当该进程退出时,分配给该进程的所有内存都将释放回操作系统。这意味着所有对象都不再存在于内存中。