【问题标题】:C# OutOfMemoryException - How to track down the culpritC# OutOfMemoryException - 如何追查罪魁祸首
【发布时间】:2011-02-17 14:00:33
【问题描述】:

我有一个 C#/WPF 应用程序,它旨在在具有 512 MB 内存的小型平板电脑上运行。如果让它继续运行,最终会抛出 OutOfMemoryException。这可能需要 12 多个小时,最多 2 天。

同时使用 ProcessExplorer 和 .NET Memory Profiler,我没有看到任何证据表明我的应用程序使用的内存随着时间的推移而增长。这只是一种典型的模式,即少量增长,然后是垃圾收集。

我添加了代码以在抛出异常时打印出所有正在运行的进程及其内存信息。我目前只是在等待它再次发生。我应该提一下,PC 是基于闪存的,并且分页功能被禁用。 512 是硬性限制。

这发生在两台不同的 PC 上。两种情况下的异常信息相同:

Top Level Exception - System.OutOfMemoryException: Insufficient memory to continue the execution of the program.
    at System.Windows.Media.Composition.DUCE+Channel.SendCommand(Byte* pCommandData, Int32 cSize)
    at System.Windows.Media.MediaContext.EnterInterlockedPresentation()
    at System.Windows.Media.MediaContext.ScheduleNextRenderOp(TimeSpan minimumDelay)
    at System.Windows.Media.MediaContext.RenderMessageHandlerCore(Object resizedCompositionTarget)
    at System.Windows.Media.MediaContext.AnimatedRenderMessageHandler(Object resizedCompositionTarget)
    at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter)
    at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)

感谢任何见解!

【问题讨论】:

  • 为什么我感觉你订阅了流氓事件。
  • 这种调试可能非常棘手,但您很可能需要创建转储并对其进行分析。 Tess 有一个很棒的博客,里面有很多实验室可以帮助你入门:blogs.msdn.com/b/tess/archive/2008/02/04/…
  • @ChaosPandion - 该死的那些流氓!你能详细说明一下吗?
  • @Tim:流氓事件订阅。当您创建一个监听事件的对象时(即thing.event += this.eventHandler)。但是,当您放弃对象时,您不会取消订阅该事件。所以发生的事情是您的对象保留在内存中,因为事件委托维护了一个引用。您必须执行 thing.event -= this.eventHandler 才能删除引用。
  • 如果是流氓事件订阅的情况,我不会看到应用程序随着时间的推移逐渐膨胀吗?我一整天都在两个系统上运行该应用程序,并使用 ProcessExplorer 观察它们。他们整天都保持在 32 到 33 MB 之间。就像突然之间,有什么事情发生了。请记住,系统没有受到任何影响,因此与应用的某些交互不会触发崩溃。

标签: c# wpf debugging out-of-memory


【解决方案1】:

由于您是“小型平板电脑”,也许您正在调用一些非“.Net”代码来控制某些硬件。是这样,也许程序的那部分可能正在使用相当多的内存(但仍然没有泄漏)。为了让垃圾收集器在这种情况下更加努力地工作,请考虑添加一个 GC.AddMemoryPressure() 调用。

【讨论】:

    【解决方案2】:

    事实证明,各种问题导致我的应用程序崩溃。我已经在另一个post here 中详细介绍了它们。

    【讨论】:

      【解决方案3】:

      我遇到了一篇非常好的文章,它深入检查了错误。

      WPF Render Thread Errors

      最有说服力的段落:不要费心去分析你得到的调用堆栈:

      不幸的是,由于设计原因,您看到的异常和调用堆栈 在 UI 线程上通常无助于诊断真正的原因 的问题。这是因为在抛出异常时, 它已经在渲染线程的故障点之后。这样 时间,渲染线程上的临界状态已经丢失,这将 帮助我们了解故障发生的位置和原因。

      【讨论】:

        猜你喜欢
        • 2015-04-09
        • 2012-05-23
        • 1970-01-01
        • 2011-01-29
        • 1970-01-01
        • 2020-10-06
        • 2022-08-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多