Memory 如何在popover中正确清理ownerWindow侦听器/JavaFX

Memory 如何在popover中正确清理ownerWindow侦听器/JavaFX,memory,memory-management,javafx-8,handler,Memory,Memory Management,Javafx 8,Handler,我用JDK8创建了一个JavaFX应用程序,它包含一个窗口和多个对象。 我现在正试图将无用的旧对象放在GarbageCollector上(使用JVisualVM进行测试) 但我遇到了一个问题:清理一个Popover,其中包含window元素上的处理程序和侦听器 popover的原始代码: 公共类CustomPopOver扩展了PopOver{ /** *具有PopOver内容的构造函数。 *@param-content节点。 */ 公共CustomPopOver(节点内容){ 超级(内容); a

我用JDK8创建了一个JavaFX应用程序,它包含一个窗口和多个对象。 我现在正试图将无用的旧对象放在GarbageCollector上(使用JVisualVM进行测试)

但我遇到了一个问题:
清理一个Popover,其中包含window元素上的处理程序和侦听器

popover的原始代码:

公共类CustomPopOver扩展了PopOver{
/**
*具有PopOver内容的构造函数。
*@param-content节点。
*/
公共CustomPopOver(节点内容){
超级(内容);
addHandler();
}
/**
*空构造函数。
*/
公共自定义Popover(){
超级();
addHandler();
}
私有void addHandler(){
this.ownerWindowProperty().addListener((可观察、旧值、新值)->{
if(newValue!=null){
EventHandler先前存在的Handler=newValue.getOnCloseRequest();
newValue.setOnCloseRequest(事件->{
if(this.isShowing()){
this.hide(Duration.millis(0));
}
if(先前存在的句柄!=null){
先前存在的句柄(事件);
}
});
}
});
}
}
我尝试了很多方法来实现这一点,但它不能正常工作:

公共类CustomPopOver扩展了PopOver实现了DisposableBean{
私有MyListener侦听器=新建MyListener();
公共CustomPopOver(节点内容){
超级(内容);
addHandler();
}
/**
*空构造函数。
*/
公共自定义Popover(){
超级();
addHandler();
}
私有void addHandler(){
this.ownerWindowProperty().addListener(listener);
}
@凌驾
公共空间销毁(){
if(this.getOwnerWindow()!=null){
this.getOwnerWindow()
.removeEventHandler(WindowEvent.WINDOW\u CLOSE\u请求,listener.windowCloseEventHandler);
this.getOwnerWindow()
.removeEventHandler(WindowEvent.WINDOW_隐藏,listener.windowHidingEventHandler);
}
this.ownerWindowProperty().RemovelListener(侦听器);
listener=null;
}
/**
*ChangeListener,在需要时删除自身。
*/
私有类MyListener实现ChangeListener{
EventHandler windowCloseEventHandler;
EventHandler windowHidingEventHandler;
@凌驾

公共虚空改变了(observeValue谢谢@fabian,在一个强引用的侦听器中,将WeakEventHandler放在Handler上,帮助清理了它

有效的代码:

公共类CustomPopOver扩展了PopOver实现了DisposableBean{
私有MyListener侦听器=新建MyListener();
/**
*具有PopOver内容的构造函数。
*@param-content节点。
*/
公共CustomPopOver(节点内容){
超级(内容);
addHandler();
}
/**
*空构造函数。
*/
公共自定义Popover(){
超级();
addHandler();
}
私有void addHandler(){
this.ownerWindowProperty().addListener(listener);
}
@凌驾
公共空间销毁(){
this.ownerWindowProperty().RemovelListener(侦听器);
listener=null;
}
/**
*ChangeListener,在需要时删除自身。
*/
私有类MyListener实现ChangeListener{
@凌驾

public void已更改(observeValue不确定通过
setOnXYZ
添加的处理程序通过
removeEventHandler
清除是否有效
setOnXYZ(null)
确实有效。顺便说一句:如果其他所有操作都失败,您可以通过使用包装来避免建立对事件处理程序的强引用。这可以通过使用
WeakReference
保存实际事件处理程序来防止通过事件处理程序建立对popover的强引用。但是,如果JavaFX保留不过,内部强烈引用了popover…@fabian谢谢,它正在与WeakEventHandler合作。