1

在过去的几天里,我一直在试图找出为什么我的 gwt 应用程序在 IE 9 上泄漏。我想与你分享我的一个发现,也许有人可以给我一个关于这里发生了什么的线索。 .我写了这个小测试:

public class Memory implements EntryPoint
{
    FlowPanel mainPanel = new FlowPanel();
    FlowPanel buttonsPanel = new FlowPanel();
    FlowPanel contentPanel = new FlowPanel();

    Timer timer;

    Date startDate;

    public void onModuleLoad()
    {
        mainPanel.setWidth("100%");
        mainPanel.setHeight("100%");

        RootPanel.get().add(mainPanel);

        Button startBtn = new Button("start test");
        startBtn.addClickHandler(new ClickHandler(){
            @Override
            public void onClick(ClickEvent event)
            {
                startDate = new Date();
                System.out.println("Started at " + startDate);
                timer = new Timer()
                {
                    public void run()
                    {
                        Date now = new Date();
                        if(isWithin5Minutes(startDate, now))
                        {
                            manageContent();
                        }
                        else
                        {
                            System.out.println("Complete at " + new Date());
                            timer.cancel();
                            contentPanel.clear();
                        }
                    }
                };
                timer.scheduleRepeating(50);
            } 
        });

        buttonsPanel.add(startBtn);

        mainPanel.add(buttonsPanel);
        mainPanel.add(contentPanel);
    }

    private void manageContent()
    {
        if(contentPanel.getWidgetCount() > 0)
        {
            contentPanel.clear();
        }
        else
        {
            for(int i =0; i < 20; i++)
            {
                Image image = new Image();
                image.setUrl("/images/test.png");
                contentPanel.add(image);
            }
        }
    }


    private boolean isWithin5Minutes(Date start, Date now)
    {
        //true if 'now' is within 5 minutes of 'start' date
    }

}

所以,我有这个定时器,它每 50 毫秒(大约 5 分钟)运行一次,并执行以下操作: - 如果面板有内容,请将其清除;- 如果面板没有内容,则添加 20 张 png 图像(30x30 透明)。

使用 sysInternals 的 Process Explorer 我得到以下结果:

即 9: 在此处输入图像描述

火狐 21.0: 在此处输入图像描述

我运行了相同的程序并进行了一些更改(.jpg 图像而不是 .png,只创建一次图像并将它们用作成员变量,使用 ClientBundle 创建图像)但结果是相同的。另外,我在生产模式下运行应用程序。

我的代码是否有问题可能导致 IE 出现这种行为?至少在计时器结束时,垃圾收集器 (GC) 不应该释放一些已使用的内存吗?你们中有人遇到过这个问题吗?

4

1 回答 1

0

IE 中的垃圾收集器是一件很奇怪的事情。例如,您可以通过简单地最小化浏览器窗口来强制它运行。我猜您的情况下的泄漏是清除容器时浏览器未正确删除的图像。尝试使用 JS “删除”操作删除它们,如下所示:

private native void utilizeElement(Element element) /*-{
  delete element;
}-*/;

然后稍微改变你的 manageContent :

    if(contentPanel.getWidgetCount() > 0)
    {
        for (Iterator<Widget> it = contentPanel.iterator(); it.hasNext();)
            utilizeElement(it.next().getElement());
        contentPanel.clear();
    }

希望这可以帮助。

于 2013-06-08T17:23:35.877 回答