如何清除javafx.scene.Scene$MouseHandler中的集合?



我有 2Pane.第一个窗格是主菜单,其children中只有Rectangle。第二个窗格是我的游戏。当我转到主菜单时,我使用以下方法来清除游戏窗格

//Fighting fighting = new Fighting();
//There is Pane fighting in fighting
if(fighting != null) {
fighting.getFighting().getChildren().clear();
fighting = null;
System.gc();
}

当我scene.setRoot(fighting.getFighting());并且不做任何事情(不要将鼠标悬停在具有OnMouse...()的对象上,不要调用移动播放器的方法)并退出主菜单(通过单击 Esc)

scene.setOnKeyPressed(event -> {
if (event.getCode()==KeyCode.ENTER) setFighting();
if (event.getCode()==KeyCode.ESCAPE) setMainMenu();
});

在这种情况下,我没有内存问题,GC 会删除无用的对象。

但是,如果我单击/悬停在任何带有listeners的对象上或在播放器上调用move(),GC 不会删除相同的对象。如果我重新进入游戏窗格并正常使用它,GC 将从以前的会话中删除对象,并且不会从当前会话中删除它们

在我的分析器中,我发现对这些无用对象的引用存储在Pane中,该ArrayList存储在Scene的匿名类MouseHandler之一中。无法添加图像好。

我还发现堆中只有 2 个Pane。其中之一是mainMenu.我已经理解了它,因为它的children只有Rectangle.第二个窗格的孩子等于children.size() == 0.

这是来自Scene&MouseHandler

的代码
private MouseHandler mouseHandler;
class MouseHandler {
/* lists needed for enter/exit events generation */
private final List<EventTarget> pdrEventTargets = new ArrayList<EventTarget>();
private final List<EventTarget> currentEventTargets = new ArrayList<EventTarget>();
private final List<EventTarget> newEventTargets = new ArrayList<EventTarget>();
private final List<EventTarget> fullPDRCurrentEventTargets = new ArrayList<EventTarget>();
private final List<EventTarget> fullPDRNewEventTargets = new ArrayList<EventTarget>();
private EventTarget fullPDRCurrentTarget = null;
}

是否可以清除这些集合或修复内存泄漏?感谢您的回答

从技术上讲,您可以使用反射API访问该列表并手动清除它,但我不确定这样做是否安全。

pdrEventTargets列表的 AFAIK 包含组件链,该组件链表示从场景到上次单击的组件的路径,并且该列表在每次单击时都会刷新。因此,如果您的情况是替换了 componens 树的一个分支,并且仍然在该列表中看到一堆关于已删除组件的引用,这些引用将在下次单击处理时由MouseHandlerpdrEventTargets中删除。至少当我在 jdk 1.8 调试时,它的行为完全一样。可能您有完全相同的行为,因此没有理由担心,至少如果这些过时的组件没有保留对某些"重"对象的引用,这些对象在删除这些组件后不应存在。在这种情况下,您应该删除该引用作为组件删除过程的一部分。

最新更新