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

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

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

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

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

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

从图像中可以看出 探查 内存使用量相当大,但数字显示它很低,在这段时间内,保留分配低于启动时…

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

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

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

-其他?

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

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

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

该技术是:

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

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

  1. 如果要在循环中分配一个对象,那么它的处理也应该包含在循环中。
  2. 如果你有多个泄漏源,它会更难发现(但仍然可能)

如果需要进一步说明,请发表评论。
祝好运…

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

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

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

已发送Microsoft的票证。

使用WebBrowsers池解决了该问题

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