2014-08-27 52 views
0

我一直在处理这个很长一段时间。有时它会抛出无效的操作异常,有时会导致内存不足。随机用户可以在一天内多次运行并崩溃。WPF应用程序与OOM异常随机崩溃

我得到了一个用户的调用堆栈,并且无法理解可能导致此问题的原因。这是一个带有丰富UI的WPF应用程序。许多观点,列表。使用PRISM和区域。

它还使用后台线程来侦听TCP,刷新数据并在UI线程上发送PRISM通知以进行更新。这个堆栈是否提供了我可能需要检查的线索?这不是起源于我的代码..

在 MS.Utility.ArrayItemList 1[[System.Windows.Freezable+FreezableContextPair, WindowsBase, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]..ctor(Int32) at MS.Utility.FrugalObjectList 1 [System.Windows.Freezable + FreezableContextPair, WindowsBase,版本= 4.0.0.0,文化=中立, 公钥= 31bf3856ad364e35 (Int32)at MS.Utility.FrugalObjectList` [[System.Windows.Freezable + FreezableContextPair, WindowsBase,Version = 4.0.0.0,Culture = neutral, PublicKeyToken = 31bf3856ad364e35]]。Insert(Int32, FreezableContextPair) at System.Windows.Freezable.AddContextToList(System.Windows.DependencyObject, System.Windows.De pendencyProperty)在 System.Windows.Freezable.AddContextInformation(System.Windows.DependencyObject, System.Windows.DependencyProperty)处 System.Windows.Freezable.AddInheritanceContext(System.Windows.DependencyObject, System.Windows.DependencyProperty) System.Windows.DependencyObject.ProvideSelfAsInheritanceContext(System.Windows.DependencyObject, System.Windows.DependencyProperty)在 System.Windows.Freezable.OnFreezablePropertyChanged(System.Windows.DependencyObject, System.Windows.DependencyObject,System.Windows.DependencyProperty)
at System.Windows.Media.RenderData.PropagateChangedHandler(System.EventHandler, 布尔型)在 System.Windows.UIElement.RenderClose(System.Windows.Media.IDrawingContent) 在 System.Windows.Media.VisualDrawingContext.CloseCore(System.Windows.Media.RenderData) 在System.Windows.Media。 RenderDataDrawingContext.DisposeCore() System.Windows.Media.DrawingContext.System.IDisposable.Dispose()at System.Windows.Media.RenderDataDrawingContext.Close()at System.Windows.UIElement.Arrange(System.Windows.Rect )在 System.Windows.Controls.DataGridCellsPanel.ArrangeChild(System.Windows.UIElement, 的Int32,ArrangeState)在 System.Windows.Controls.DataGridCellsPanel.ArrangeOverride(System.Windows.Size) 在System.Windows.FrameworkElemen t.ArrangeCore(System.Windows.Rect)
at System.Windows.UIElement.Arrange(System.Windows.Rect)at MS.Internal.Helper.ArrangeElementWithSingleChild(System.Windows.UIElement, System.Windows.Size)在 System.Windows.Controls.ItemsPresenter.ArrangeOverride(System.Windows.Size) 在System.Windows.FrameworkElement.ArrangeCore(System.Windows.Rect)
在System.Windows.UIElement.Arrange(System.Windows.Rect )在 System.Windows.Controls.Control.ArrangeOverride(System.Windows.Size)
在 System.Windows.Controls.Primitives.DataGridCellsPresenter.ArrangeOverride(System.Windows.Size) 在System.Windows.FrameworkE lement.ArrangeCore(System.Windows。矩形)
在System.Windows.UIElement.Arrange(System.Windows.Rect)在 System.Windows.Controls.Grid.ArrangeOverride(System.Windows.Size)
在System.Windows.FrameworkElement.ArrangeCore(系统。 Windows.Rect)
在System.Windows.UIElement.Arrange(System.Windows.Rect)在 System.Windows.Controls.Border.ArrangeOverride(System.Windows.Size)
在System.Windows.FrameworkElement.ArrangeCore( System.Windows.Rect)
at System.Windows.UIElement.Arrange(System.Windows.Rect)at System.Windows.Controls.Control.ArrangeOverride(System.Windows.Size)
at System.Windows.Controls.DataGridRow.ArrangeOverride(System.Windows.Size) at System.Windows.FrameworkElement.ArrangeCore(System.Windows.Rect)
at System.Windows.UIElement.Arrange(System.Windows.Rect)在 System.Windows.Controls.VirtualizingStackPanel.ArrangeOtherItemsInExtendedViewport(布尔, System.Windows.UIElement,System.Windows.Size,双,的Int32, System.Windows.Rect的ByRef,System.Windows.Size的ByRef, System.Windows .Point ByRef,Int32 ByRef)at System.Windows.Controls.VirtualizingStackPanel.ArrangeOverride(System.Windows.Size) at System.Windows.FrameworkElement.ArrangeCore(System.Windows.Rect)
at System.Windows.UIElement .Arrange(System.Windows.Rect)在 System.Windows.ContextLayoutManager.UpdateLayout()在 System.Windows.ContextLayoutManager.UpdateLayoutCallback(System.Object的) 在System.Windows.Media.MediaContext + InvokeOnRenderCallback.DoWork()
处 System.Windows.Media.MediaContext.RenderMessageHandler(System.Object的)System.Windows.Media.MediaContext.FireInvokeOnRenderCallbacks()
在 System.Windows.Media.MediaContext.RenderMessageHandlerCore(System.Object的) 在 MS.Intern。System.InWindows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate, System.Object,Int32)at al.Threading.ExceptionFilterHelper.TryCatchWhen(System.Object的, System.Delegate,System.Object的,的Int32,System.Delegate)在 System.Windows.Threading.DispatcherOperation.InvokeImpl()在 System.Windows.Threading.DispatcherOperation。 InvokeInSecurityContext(System.Object的) 处 System.Threading.ExecutionContext.Run(的System.Threading System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback,System.Object的,布尔值)。 ExecutionContext, System.Threading.ContextCallback,System.Object,Boolean) System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback,System.Object)at System.Windows.Threading.DispatcherOperation.Invoke()在 System.Windows.Threading.Dispatcher.ProcessQueue()在 System.Windows.Threading.Dispatcher.WndProcHook(IntPtr的,的Int32,IntPtr的, IntPtr的,布尔的ByRef)在MS.Win32.HwndWrapper.WndProc(IntPtr, Int32,IntPtr,IntPtr,Boolean ByRef)at MS.Win32.HwndSubclass.DispatcherCallbackOperation(System.Object)at System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate, System.Object的,Int32)将在在 System.Windows.Threading.Dispatcher.LegacyInvokeImpl MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(System.Object的, System.Delegate,System.Object的,的Int32,System.Delegate)( System.Windows。Threading.DispatcherPriority, System.TimeSpan,System.Delegate,System.Object的,Int32)将在 MS.Win32.HwndSubclass.SubclassWndProc(IntPtr的,的Int32,IntPtr的,IntPtr的)
在 MS.Win32.UnsafeNativeMethods.DispatchMessage(系统.Windows.Interop.MSG 的ByRef)在 System.Windows.Threading.Dispatcher.PushFrameImpl(System.Windows.Threading.DispatcherFrame) 在 System.Windows.Threading.Dispatcher.PushFrame(System.Windows.Threading.DispatcherFrame) at System.Windows.Threading.Dispatcher.Run()at System.Windows.Application.RunDispatcher(System.Object)at System.Windows.Application.RunInternal(System.Windows.Window)at System.Windows.Application.Run(System.Windows.Window)在 ArturExpress.Main.App.Main()

+0

我建议使用一些分析器来查看实际发生的事情。从描述中很难猜出... – walther 2014-08-27 14:34:04

+0

堆栈跟踪的实际异常是什么?是OutOfMemoryException还是别的?另外,有没有内部的例外? – user469104 2014-08-27 14:35:09

+0

不幸的是我无法追查它。这是不可复制的,随机发生在用户机器上(可以好几天)。该堆栈跟踪来自事件日志。这是OutOfMemoryException。 – katit 2014-08-27 14:41:37

回答

1

有一个set_Capacity通常会导致尝试分配连续的内存块。如果它足够大,将从大型对象堆中请求,而这个堆没有压缩,因此碎片会导致难以找到连续的内存块来满足请求。

内存分析器将是我的下一步,但如果您正在获取其他类型的异常,那么日志记录会更好。

对于桌面应用程序,我将log4net与内存记录器一起使用,其中包含最近500条消息的详细信息日志。如果发生异常,我会把它指向一个文件,这样我就会有一个非常详细的上下文导致异常。

注意调整某些集合的容量通常需要增长阵列所需内存的3倍。这是因为,当它们超过当前容量时,它们会分配一个两倍于当前大小的新数组,并将现有项目复制到新数组中。因此,在此过渡期间,集合需要3倍的内存,当前阵列正在从中复制,而两倍大的阵列将被复制到内存中。我不知道这是不是在这里发生。当您的阵列容量经常增长时,您通常会在内存配置文件中看到一个渐增的锯齿图案。

+0

嗯..列表不大,也许是400个项目。通过移除插入来更新项目(这是让可观察数组工作的最佳方式),但没有什么超级疯狂。我使用内存分析器进行了本地测试,没有发生任何奇怪的事情一切都很正常,我甚至做了一些压力测试,发现异常的高负载(甚至接近真实),并且内存飙升,但在GC进入后却下降了。 – katit 2014-08-27 15:14:28

+0

像用户一样尝试几个小时,看它是否逐步使用更多的记忆。如果有泄漏,你会开始看到每次GC启动后,它不会下降。如果正在引用不再需要的对象,则可以在C#中获得“泄漏”。即您从一个列表中删除项目,但它们仍然在内部从UI框架引用。无论是大量的测试还是增加详细的日志记录来试图确定问题出现的情况。否则,我们在黑暗中拍摄。 – AaronLS 2014-08-27 15:25:42

+0

是的,我知道..我确实监控了一天的应用程序。没什么奇怪的用户不会整体抱怨。有70个用户,偶尔有一个用户开始抱怨崩溃。它就像这样“最近工作的很好,本周它每天可能会崩溃一次,但是昨天我无法工作,因为它一直在崩溃。”我是在指责线程代码。审核所有内容,随处记录错误。没有结果... – katit 2014-08-27 15:28:20

1

我们可以从这个堆栈跟踪确定的是,内存溢出异常期间发生一个StackPanel的UpdateLayout,其中包含一个DataGrid。

当其中一个DataGrid行被要求重新排列自己时,看起来是冻结列的一部分的一个单元格(似乎包含一个面板)最终要么从冻结到未冻结相反),此时尝试构建FreezableContextPair对象时发生内存不足异常。

无论这是否是巧合还是因果关系都不可能说没有额外的数据点。换句话说,如果有10个栈跟踪显示完全相同的跟踪,那么它可能是一组特定的事件,与您的某个网格有一列从冻结到不可解冻,出于某种原因会导致内存不足异常。

如果其他堆栈跟踪显示完全不同的结果,那么这个特定的例外可能是巧合的,例如,一些东西将内存使用推到了边缘,而这种特殊的操作恰好是把它推到边缘的那个。

您需要更多的数据点来确定并且应该要求您的用户在发生这种情况时开始发送堆栈跟踪+在内存分析器中运行应用程序以查看是否可以看到任何异常。

相关问题