1

我有一个 GWT 2.4 应用程序,我通过将一个小部件切换到另一个Composite小部件来“交换视图”,分别RootPanel使用通常的RootPanel.get().clear()RootPanel.get().add(newWidget)删除和添加。

第一个复合小部件包含一个PasswordTextBox. 它侦听触发交换的 Enter 按键。没什么太花哨的:

getDisplay().getPasswordBoxForKeyPresses().addKeyPressHandler(new KeyPressHandler() {
    public void onKeyPress(KeyPressEvent event) {
        if (event.getNativeEvent().getKeyCode() == KeyCodes.KEY_ENTER) {
            swapWidgets(); // clear RootPanel and add new widget
        }
    }
});

问题是存在 DOM 内存泄漏:在RootPanel.get().clear()调用之后,旧的复合小部件卡在分离的 DOM 树中,因为HTMLInputElementforPasswordTextBox对它有一些我无法识别的奇怪引用。

更新: 我采纳了以下有用的建议,在 style=detailed 编译并开始尝试沿着树向下查找对 JS 中元素的引用。我对 GWT 很陌生,所以对我来说仍然不清楚发生了什么。因此,从保留树的第二行开始,我可以看到其中lastEvent包含_2nativeKeyTarget顶部列出的内容。但我从那里去哪里? 在此处输入图像描述

4

2 回答 2

0

看起来您可能没有跟踪处理程序注册,这将导致内存泄漏、阻止对象被恢复并导致幻像事件捕获。

在纯 GWT 中,它看起来像这样

// class member
HandlerRegistration reg;

// save for recovery
reg = getDisplay().getPasswordBoxForKeyPresses().addKeyPressHandler(...);

public void onDetatch() {
// recover memory
reg.removeHandler();
reg = null;
}

GXT 有一个很好的分组功能来防止注册蔓延,它看起来像这样

// class member
GroupingHandlerRegistration regs = new GroupingHandlerRegistration();
// save for later recovery
regs.add( getDisplay().getPasswordBoxForKeyPresses().addKeyPressHandler(...) );
// recover memory
regs.removeHandler();

GroupingHandlerRegistration 的源代码

于 2013-11-16T02:41:06.253 回答
0

我追踪了对 SmartGWT 的引用。它跟踪 ISC_Core.js 中的最后一次点击事件。进一步的问题是

  1. 此行为将如何进一步影响我的应用程序中的内存使用?
  2. 如果需要,可以绕过这种行为吗?

但这些问题是另一篇文章!

于 2013-11-16T00:07:39.360 回答