起因

程序发布后,运行突然奔溃报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. 刚刚明白了for循环写三角形

    for(int a = 15; a >=1; a--) { for(int b = a - 1; b >=0; b--) { System.out.print("A") ...

  2. Petya and Array (权值线段树+逆序对)

    Petya and Array http://codeforces.com/problemset/problem/1042/D time limit per test 2 seconds memory ...

  3. JS 图片切换

    <%@ Page Language="C#" AutoEventWireup="true" CodeFile="zzzz.aspx.cs&quo ...

  4. 【转】Repository 返回 IQueryable?还是 IEnumerable?

    这是一个很有意思的问题,我们一步一步来探讨,首先需要明确两个概念(来自 MSDN): IQueryable:提供对未指定数据类型的特定数据源的查询进行计算的功能. IEnumerable:公开枚举数, ...

  5. PythonQt进阶

    本文介绍PythonQt和qt之间是如何进行交互操作的 例子是以Qt的TreeView为实例进行介绍 在该例子中,TreeItem不是从Qt中进行的继承,这样的类如果要和Python进行交互,首先需要 ...

  6. [Sikuli] Sikuli安装

    http://blog.csdn.net/defectfinder/article/details/49819215 1.下载 sikulixsetup-1.1.0.jar (md5, sig) ht ...

  7. boost::asio 学习草稿

    http://www.gamedev.net/blog/950/entry-2249317-a-guide-to-getting-started-with-boostasio/ 可以多个线程拥有io_ ...

  8. part1:8-远程登录Linux

    Linux远程登录 Linux系统中是通过ssh服务实现的远程登录功能.默认ssh服务开启了22端口,而且在安装完成系统时,这个服务已经安装,并且是开机启动的.所以不需要额外配置就能直接远程登录Lin ...

  9. 在jsp中怎么使用Cookie?el表达式中获取cookie的问题

    初学jsp,不清楚cookie的使用方法,希望高手指点一下!   一般来说有两种办法,在JSP中使用Java的嵌入脚本. 例如: 写入Cookie <html> <head>. ...

  10. 2018.10.02 NOIP模拟 序列维护(线段树+广义欧拉定理)

    传送门 一道比较好的线段树. 考试时线性筛打错了于是弃疗. 60分暴力中有20分的快速幂乘爆了于是最后40分滚粗. 正解并不难想. 每次区间加打懒标记就行了. 区间查询要用到广义欧拉定理. 我们会发现 ...