什么可能导致这个内存问题?

时间:2013-07-31 16:09:14

标签: c# xaml memory windows-phone-8 webbrowser-control

我正在开发一款适用于Windows Phone 8的应用程序,而且我遇到了内存泄漏问题。但首先是一些背景。该应用程序(不幸的是)使用WebBrowsers作为页面。这些页面非常复杂,涉及大量的JavaScript。

应用程序的本机部分,用c#编写,负责与javascript进行一些简单的通信(例如,native是javascript与服务器通信的委托),制作用于页面转换,跟踪,持久性的动画,所有这些都是在一个独特的PhoneApplicationPage中完成的。

我因为内存异常而崩溃了,我开始分析应用程序。我可以看到WebBrowsers,它是应用程序的重要组成部分,正在正确处理。 但我看到的问题是内存不断增加。更糟糕的是,我对分析器的反馈很少。根据我的理解,分析器图表说存在一个大问题,而分析器数据表明根本没有问题......

注意:该步骤表示从WebBrowser到另一个WebBrowser的导航。通过两个控件之间的动画创建(我猜)尖峰。在我在图像中选择的范围中,我正在向前导航,一个向后进行最多5个WebBrowsers(2个用于总是存在的菜单,1个用于索引页,1个用于我导航的页面和1个对于我导航到的页面)。在每个导航中,探查器显示正确数量的WebBrowsers:向前导航后为5,向后导航后为4。

注2:我添加了红线,以便更清楚地了解内存在这段时间内上升

从图像中可以看出 profiler 内存使用量相当大,但数字显示它很低,在这段时间内,保留分配比开始时更低......

我希望我已经提供了足够的信息。我想知道可能导致这个问题的一些想法。到目前为止,我的想法是:

- WebBrowser中的javascript做错了(例如没有清理某些事件处理程序)。即使是这种情况,WebBrowser也不应该在销毁时释放内存吗?

- 使用一个独特的PhoneApplicationPage是不应该做的事情,改变它的结构可能会导致这种情况。

- 其他?

另一个问题:为什么图表显示正确的内存使用量而数字没有?

如果您需要有关探查器的更多信息,请询问,我明天会发布。

3 个答案:

答案 0 :(得分:1)

我认为没有足够的信息可以找到泄漏的原因,如果没有发布您的整个解决方案,我不确定是否可以,因为问题是找到它的根本原因...
我能提供的是当我有自己的内存泄漏时使用的方法。

技术是:

  1. 打开内存探查器。从你的截图我看到你正在使用一个。我用了perfmonThis文章提供了一些关于设置perfmon的内容,@fmunkert也很好地解释了它。
  2. 在代码中找到您怀疑泄漏可能位于该区域的区域。这部分主要取决于您对代码中负责该问题的部分有很好的猜测。
  3. 将泄漏推至极端:使用标签和“goto”隔离区域/功能并多次重复可疑代码(循环将起作用。我发现goto更方便了物质)。
  4. 在循环中,我使用了断点,每50次命中停止一次,以检查内存使用量的增量。当然,您可以将值更改为应用程序中明显的泄漏更改。
  5. 如果找到导致泄漏的区域,则内存使用量应迅速增加。如果内存使用量没有增加,请使用您怀疑是根本原因的另一个代码区域重复1-4阶段。如果是,请继续6。
  6. 在您发现原因的区域,使用相同的技术(转到+标签)放大并隔离区域的较小部分,直到找到泄漏源(请不要为了递归而向我投票)步......:0))。
  7. 请注意,此方法的缺点是:

    1. 如果你在循环中分配一个对象,它的处理也应该包含在循环中。
    2. 如果你有多个泄漏源,那就更难发现(但仍然可能)
    3. 如果需要进一步说明,请发表评论 祝你好运......

答案 1 :(得分:1)

经过大量调查后我终于找到了泄漏。 泄漏是由WebBrowser控件本身创建的,它似乎有一些事件处理程序在从Panel中删除时不会被删除。实际上,通过以下步骤可以重现泄漏:

  1. 创建新的WebBrowser
  2. 将其添加到面板或其他任何
  3. 导航到一个页面,图片大而重
  4. 点击浏览器空白处的某个位置(点击图片似乎不会造成泄漏)
  5. 删除并收集浏览器
  6. 从1
  7. 重复

    在每次迭代时,永远不会收集图像的内存,并且内存会继续增长。

    已发送微软票。

    使用WebBrowsers池解决了问题

答案 2 :(得分:0)

你清理过你的事件处理程序了吗?如果控件是root用户,您可能会无意中仍然有一些引用。