8

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

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

在我因内存不足异常而崩溃后,我开始分析应用程序。我可以看到作为应用程序重要组成部分的 Web 浏览器正在正确处理。但我看到的问题是内存继续增加。更糟糕的是,我从探查器那里得到的反馈很少。据我了解,分析器图表说有一个大问题,而分析器数字说根本没有问题......

注意:该步骤表示从 WebBrowser 到另一个 WebBrowser 的导航。尖峰是由两个控件之间的动画创建的(我想)。在我在图像中选择的跨度中,我正在进行向前导航和向后导航,最多有 5 个 Web 浏览器(2 个用于始终存在的菜单,1 个用于索引页面,1 个用于我导航的页面和 1 个对于我导航到的页面)。在每次导航时,分析器都会显示正确数量的 WebBrowser:向前导航后 5 个,向后导航后 4 个。

注2:我添加了红线以更清楚地表明内存在这段时间内正在上升

正如您从图像中看到的那样 剖析器 ,内存使用量非常大,但数字表明它很低,并且在这段时间内,保留分配比开始时要低......

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

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

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

-其他?

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

如果您需要有关分析器的更多信息,请询问,我将在明天发布。

4

3 回答 3

1

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

该技术是:

  1. 打开内存分析器。从您的屏幕截图中,我看到您正在使用一个。我使用了 perfmon本文有一些关于设置 perfmon 的材料,@fmunkert也很好地解释了它。
  2. 在代码中找到您怀疑泄漏可能在该区域的区域。这部分主要取决于您对导致问题的代码部分有很好的猜测。
  3. 将泄漏推到极致:使用标签和“goto”来隔离区域/功能并多次重复可疑代码(循环将起作用。我发现 goto 更方便)。
  4. 在循环中,我使用了一个断点,它每 50 次命中就停止一次,以检查内存使用量的增量。当然,您可以更改该值以适应应用程序中明显的泄漏变化。
  5. 如果您找到了导致泄漏的区域,则内存使用量应该会迅速飙升。如果内存使用量没有达到峰值,请使用您怀疑是根本原因的另一个代码区域重复阶段 1-4。如果是,请继续执行 6。
  6. 在您发现原因的区域中,使用相同的技术(goto + 标签)放大并隔离该区域的较小部分,直到找到泄漏源。

请注意,此方法的缺点是:

  1. 如果你在循环中分配一个对象,它的处置也应该包含在循环中。
  2. 如果您有多个泄漏源,则更难发现(但仍有可能)
于 2013-08-05T08:19:58.630 回答
1

好的,经过大量调查,我终于能够找到泄漏点。泄漏是由 WebBrowser 控件本身创建的,当您将其从面板中删除时,该控件似乎具有一些未删除的事件处理程序。事实上,通过以下步骤可以重现泄漏:

  1. 创建一个新的网络浏览器
  2. 将其添加到面板或其他任何东西
  3. 导航到一个页面,其中包含一个又大又重的图像
  4. 点击浏览器空白处的某处(点击图像似乎不会造成泄漏)
  5. 删除并收集浏览器
  6. 从 1 重复

在每次迭代中,图像的内存都不会被收集,并且内存会继续增长。

Microsoft 的票已发送。

使用 WebBrowsers 池解决了该问题

于 2013-09-03T13:16:54.397 回答
0

你清理你的事件处理程序了吗?如果控件已植根,您可能会无意中仍有一些参考。

于 2013-08-27T06:30:30.867 回答