起因

程序发布后,运行突然奔溃报Out of Memory,查看日志发现如下类似错误(以下堆栈信息来之网络):

System.OutOfMemoryException: Insufficient memory to continue the execution of the program.
   at System.Windows.Media.Composition.DUCE.Channel.SyncFlush()
   at System.Windows.Media.MediaContext.CompleteRender()
   at System.Windows.Interop.HwndTarget.OnResize()
   at System.Windows.Interop.HwndTarget.HandleMessage(Int32 msg, IntPtr wparam, IntPtr lparam)
   at System.Windows.Interop.HwndSource.HwndTargetFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
   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)

或是

  at System.Windows.Media.Composition.DUCE.Channel.SyncFlush()
at System.Windows.Interop.HwndTarget.UpdateWindowSettings(Boolean enableRenderTarget, Nullable`1 channelSet)
at System.Windows.Interop.HwndTarget.UpdateWindowPos(IntPtr lParam)
at System.Windows.Interop.HwndTarget.HandleMessage(WindowMessage msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Interop.HwndSource.HwndTargetFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)

问题现象

这个现象主要发生于XP系统,至少在我自己的一台XP系统发生了,当然最关键的是在领导的XP系统也发生了。

更不幸的是eventvwr也未招供任何信息,网络搜索结果也是一堆问题,但是都没解决方案,有说是由于WPF的透明度、颜色问题,显卡驱动问题,但都直接被下面的答案否了,人家说根本没用。

在领导机器发生时,虽然使用visual studio 2010调试,但无任何特殊提示,就突然报了异常。我们把主窗口换成了一个空白的窗口,现象没有发生;尝试着打开dxdiag关掉了硬件加速还是报错,不过重新编译后再运行又正常了,之后再打开硬件加速,不管如何折腾问题都不再重现。当时推断和dxdiag有关,但由于版本发布匆忙,还有多处已知内存泄漏,加之空白窗口没问题,一度怀疑是自己程序问题。

接着的几天便是没日没夜的对电脑进行摧残,终于黄天不负有心人,在我机器上得到重现,通过一步步排查,发现当程序未使用最大化打开时是正常的,使用最大化模式打开后便报类似错误,使用正常窗体(也就是默认大小)打开点击最大按钮也报错。这时才发现一直冤枉了一张只有40多K的PNG图片(1600*600),因为有没有它现象依旧。

Dump文件也是没问题,虽然我曾一顿纠结于在没有抓Dump就关闭了硬件加速,但后来发现即使有Dump文件也基本没用。

由于重现是比较随机的,在“玩弄”了几次之后,我的机器又恢复了正常,但发现以下现象:

1.windows自带的mspaint无法粘贴图片了,报“获取剪切板数据出错”的错误。

2.运行CLIPBRD,发现不能显示图片,且显示如下信息“剪切板查看器无法以当前格式显示信息,或没有足够的内存显示信息,请退出一个或多个应用程序以增加可用内存”。

3.即使mspaint能粘贴图片了图片也是黑底的。

4.物理内存、CPU都比较正常,但CPU多用于内核使用(通过ProcessExplorer)。

问题原因

内存确实不够,那么是哪个内存导致的结果,虚拟内存,物理内存、显卡内存?还是共同作用的结果。

1.针对性的分别把虚拟内存设置在系统盘,并在100M-200M之间,系统盘磁盘空间小于80M

2.使用C#,通过new Byte,一直来占据内存。

3.使用C#,一直加载一张接近2M的图片,一直来占据显存

通过实验发现,除了显存一项外其他都不会影响测试结果,通过第三项能有机率还原之前的异常,当然物理内存不够也会报错,只是会随机的在XAML加载时便会报错,而不是本文报的这个错。

解决问题

既然发现了原因,那么如何解决?

告诉客户使用运行打开dxdiag,在显示也中禁用硬件加速,之后重新启动计算机。

那么我们程序能做什么?

1.在程序启动时,判断显存是否足够,当然这需要API支持。intel,N卡,A卡都有自己方法可以使用,具体请自行网络搜索。

2.什么都不做。是的,你没看错,而且这是我们最后定下的解决方案!这得感谢GPU-Z的这款可查看显存使用量的软件,它告诉我们有些显卡是无法查看显存的,而能查看显存的机器似乎都不会报这个错误。我的机器是联想的一体机,显卡型号为Intel(R) G41 Express Chipest,欢迎测试拍砖。

当然我们也想过是否对主窗口的内容进行修减,但这又未尝不是一件好事,启动时就报错总好过业务做了一半再报错。

PS:

这个BUG网上有说是WPF的问题,因为其他程序基本没出现过。

2013-12-17 追加:由于我们的窗体是没有边框的,所以AllowTransparency属性为false,这种几率会降低(降低不是说没有),另外再必现这种问题时,打开Chrome浏览器开N个网页都没问题,怀疑是显卡内存比较碎,而WPF一次分配过大所至,而且发生这种显存问题都是因为feiqiu?每次有问题它都打开,关了就没问题了。

WPF Out Of Memory的更多相关文章

  1. 【NX二次开发】NX内部函数,libugui.dll文件中的内部函数

    本文分为两部分:"带参数的函数"和 "带修饰的函数". 浏览这篇博客前请先阅读: [NX二次开发]NX内部函数,查找内部函数的方法 带参数的函数: bool A ...

  2. A memory leak issue with WPF Command Binding

    Background In our application, we have a screen which hosts several tabs. In each tab, it contains a ...

  3. WPF WebBrowser Memory Leak 问题及临时解决方法

    首先介绍一下内存泄漏(Memory Leak)的概念,内存泄露是指程序中已动态分配的堆内存由于某种原因未释放或者无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果. 最近在使用W ...

  4. WPF ICommandSource Implementations Leak Memory!

    Actually the title of this article should be entitled "How to use WeakEventManager with IComman ...

  5. 年度巨献-WPF项目开发过程中WPF小知识点汇总(原创+摘抄)

    WPF中Style的使用 Styel在英文中解释为”样式“,在Web开发中,css为层叠样式表,自从.net3.0推出WPF以来,WPF也有样式一说,通过设置样式,使其WPF控件外观更加美化同时减少了 ...

  6. WPF与WinForm开发有什么区别?

    转自http://hi.baidu.com/leoliu83/blog/item/1d1a4a66dcb41134aa184cfd.html WPF开发于WinForm之后,从技术发展的角度,WPF比 ...

  7. Windows And Video Memory

    MSDN Blogs > Zemblanity > Windows And Video Memory   Windows And Video Memory Tom_Mulcahy 11 F ...

  8. WPF自定义控件与样式(14)-轻量MVVM模式实践

    一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. MVVM是WPF中一个非 ...

  9. WPF之依赖属性

    Introduction When you begin to develop appliations with WPF, you will soon stumble across Dependency ...

随机推荐

  1. LOG4J spring与mybatis整合

    1.导入包log4j-1.2.17.jar <dependency>            <groupId>log4j</groupId>            ...

  2. fieldOfView

    fieldOfView 属性 fieldOfView:Number 语言版本:  ActionScript 3.0 运行时版本:  Flash Player 10, AIR 1.5 为三维视野指定一个 ...

  3. [leetcode]340. Longest Substring with At Most K Distinct Characters至多包含K种字符的最长子串

    Given a string, find the length of the longest substring T that contains at most k distinct characte ...

  4. popupMenu-----弹出菜单

    import android.os.Bundle; import android.app.Activity; import android.graphics.Color; import android ...

  5. HTML 视频(Videos)

    前端video做起来很简单,但是还是需要做一些记录,不然下次再做相关的业务仍得费时间找. 参考地址: http://www.jq22.com/jquery-info404 http://www.run ...

  6. 在控制台远程连接mysql数据库时,出现ERROR 2049 (HY000)错误

    问题的原因是,你本地的数据库版本过高,而远程的数据库版本低. 解决方法:在连接时加上  --skip-secure-auth 参数就可以了. mysql -h主机 -u用户名 -p密码 --skip- ...

  7. NPOI导入导出Excel数据

    代码: using NPOI.HSSF.UserModel; using NPOI.SS.UserModel; using NPOI.XSSF.UserModel; using System; usi ...

  8. 21个ui设计技巧,让你的设计不落伍

    1.功能性极简主义 不少移动端APP和网站开始基于极简主义设计风来设计,而极简主义本身并非关注所有的信息,而是通过减少非关键信息来突出特定的内容,它是有着极强的功能性和偏向的.它有着如下的特征: ・简 ...

  9. swift http post json + 登录

    var nsUrl : NSURL = NSURL(string:API_HOST+"/"+LOGIN_API)! var request = NSMutableURLReques ...

  10. 调用数据库--stone

    from Mysql_operate_class import mysql def saveMysqlData(sql, dbname="algorithm"): pym = my ...