程序發佈後,運行忽然奔潰報Out of Memory,查看日誌發現以下相似錯誤(如下堆棧信息來之網絡):windows
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系統也發生了。app
更不幸的是eventvwr也未招供任何信息,網絡搜索結果也是一堆問題,可是都沒解決方案,有說是因爲WPF的透明度、顏色問題,顯卡驅動問題,但都直接被下面的答案否了,人家說根本沒用。測試
在領導機器發生時,雖然使用visual studio 2010調試,但無任何特殊提示,就忽然報了異常。咱們把主窗口換成了一個空白的窗口,現象沒有發生;嘗試着打開dxdiag關掉了硬件加速仍是報錯,不太重新編譯後再運行又正常了,以後再打開硬件加速,無論如何折騰問題都再也不重現。當時推斷和dxdiag有關,但因爲版本發佈匆忙,還有多處已知內存泄漏,加之空白窗口沒問題,一度懷疑是本身程序問題。spa
接着的幾天即是沒日沒夜的對電腦進行摧殘,終於黃天不負有心人,在我機器上獲得重現,經過一步步排查,發現當程序未使用最大化打開時是正常的,使用最大化模式打開後便報相似錯誤,使用正常窗體(也就是默認大小)打開點擊最大按鈕也報錯。這時才發現一直冤枉了一張只有40多K的PNG圖片(1600*600),由於有沒有它現象依舊。調試
Dump文件也是沒問題,雖然我曾一頓糾結於在沒有抓Dump就關閉了硬件加速,但後來發現即便有Dump文件也基本沒用。日誌
因爲重現是比較隨機的,在「玩弄」了幾回以後,個人機器又恢復了正常,但發現如下現象:code
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?每次有問題它都打開,關了就沒問題了。