【问题标题】:C# System.ComponentModel.Win32Exception (0x80004005): Not enough storage is available to process this commandC# System.ComponentModel.Win32Exception (0x80004005):没有足够的存储空间来处理这个命令
【发布时间】:2018-10-24 12:45:27
【问题描述】:

长时间(一到两周)运行我的应用程序(.Net 4.5、64 位、WPF)后,我遇到以下应用程序崩溃:

Faulting application name: XY.exe, Version: 2.12.2.2, Time: 0x5bade142
Faulting module name: KERNELBASE.dll, Version: 6.1.7601.24150, Time: 0x5b0cbc65
Exception code: 0xe0434352
Fault offset: 0x000000000001a06d
Faulting process id: 0x8694
Faulting application start time: 0x01d457228a130410
Faulting application path: C:\Testsysteme\YY.exe
Faulting module path: C:\Windows\system32\KERNELBASE.dll
Report Id: dbfc630b-c61f-11e8-bc27-1866da0d15ef

Application: XY.exe
Frameworkversion: v4.0.30319
Description: The process was terminated due to an unhandled exception
Exception information: System.ComponentModel.Win32Exception
at MS.Win32.UnsafeNativeMethods.RegisterClassEx(WNDCLASSEX_D)
at MS.Win32.HwndWrapper..ctor(Int32, Int32, Int32, Int32, Int32, Int32, Int32, System.String, IntPtr, MS.Win32.HwndWrapperHook[])
at System.Windows.Interop.HwndSource.Initialize(System.Windows.Interop.HwndSourceParameters)
at System.Windows.Interop.HwndSource..ctor(System.Windows.Interop.HwndSourceParameters)
at System.Windows.Controls.Primitives.Popup+PopupSecurityHelper.BuildWindow(Int32, Int32, System.Windows.Media.Visual, Boolean, System.Windows.Interop.HwndSourceHook, System.Windows.AutoResizedEventHandler)
at System.Windows.Controls.Primitives.Popup.BuildWindow(System.Windows.Media.Visual)
at System.Windows.Controls.Primitives.Popup.CreateWindow(Boolean)
at System.Windows.Controls.Primitives.Popup.OnIsOpenChanged(System.Windows.DependencyObject, System.Windows.DependencyPropertyChangedEventArgs)
at System.Windows.DependencyObject.OnPropertyChanged(System.Windows.DependencyPropertyChangedEventArgs)
at System.Windows.FrameworkElement.OnPropertyChanged(System.Windows.DependencyPropertyChangedEventArgs)
at System.Windows.DependencyObject.NotifyPropertyChange(System.Windows.DependencyPropertyChangedEventArgs)
at System.Windows.DependencyObject.UpdateEffectiveValue(System.Windows.EntryIndex, System.Windows.DependencyProperty, System.Windows.PropertyMetadata, System.Windows.EffectiveValueEntry, System.Windows.EffectiveValueEntry ByRef, Boolean, Boolean, System.Windows.OperationType)
at System.Windows.DependencyObject.SetValueCommon(System.Windows.DependencyProperty, System.Object, System.Windows.PropertyMetadata, Boolean, Boolean, System.Windows.OperationType, Boolean)
at System.Windows.Data.BindingOperations.SetBinding(System.Windows.DependencyObject, System.Windows.DependencyProperty, System.Windows.Data.BindingBase)
at System.Windows.Controls.Primitives.Popup.CreateRootPopup(System.Windows.Controls.Primitives.Popup, System.Windows.UIElement)
at System.Windows.Controls.ToolTip.OnIsOpenChanged(System.Windows.DependencyObject, System.Windows.DependencyPropertyChangedEventArgs)
at System.Windows.DependencyObject.OnPropertyChanged(System.Windows.DependencyPropertyChangedEventArgs)
at System.Windows.FrameworkElement.OnPropertyChanged(System.Windows.DependencyPropertyChangedEventArgs)
at System.Windows.DependencyObject.NotifyPropertyChange(System.Windows.DependencyPropertyChangedEventArgs)
at System.Windows.DependencyObject.UpdateEffectiveValue(System.Windows.EntryIndex, System.Windows.DependencyProperty, System.Windows.PropertyMetadata, System.Windows.EffectiveValueEntry, System.Windows.EffectiveValueEntry ByRef, Boolean, Boolean, System.Windows.OperationType)
at System.Windows.DependencyObject.SetValueCommon(System.Windows.DependencyProperty, System.Object, System.Windows.PropertyMetadata, Boolean, Boolean, System.Windows.OperationType, Boolean)
at System.Windows.DependencyObject.SetValue(System.Windows.DependencyProperty, System.Object)
at System.Windows.Controls.PopupControlService.RaiseToolTipOpeningEvent()
at System.Windows.Threading.DispatcherTimer.FireTick(System.Object)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate, System.Object, Int32)
at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(System.Object, System.Delegate, System.Object, Int32, System.Delegate)
at System.Windows.Threading.DispatcherOperation.InvokeImpl()
at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
at MS.Internal.CulturePreservingExecutionContext.Run(MS.Internal.CulturePreservingExecutionContext, System.Threading.ContextCallback, System.Object)
at System.Windows.Threading.DispatcherOperation.Invoke()
at System.Windows.Threading.Dispatcher.ProcessQueue()
at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr, Int32, IntPtr, IntPtr, Boolean ByRef)
at 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)
at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(System.Object, System.Delegate, System.Object, Int32, System.Delegate)
at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(System.Windows.Threading.DispatcherPriority, System.TimeSpan, System.Delegate, System.Object, Int32)
at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr, Int32, IntPtr, IntPtr)
at MS.Win32.UnsafeNativeMethods.DispatchMessage(System.Windows.Interop.MSG ByRef)
at System.Windows.Threading.Dispatcher.PushFrameImpl(System.Windows.Threading.DispatcherFrame)
at System.Windows.Application.RunDispatcher(System.Object)
at System.Windows.Application.RunInternal(System.Windows.Window)
at XY.App.Main()

未处理异常的日志另外显示:

System.ComponentModel.Win32Exception (0x80004005): Not enough storage is available to process this command

我已经找到了一个包含问题基本描述的链接connect.microsoft.com on web.archive.org,我从JordiCorbilla/atom-table-monitor (GitHub) 下载并运行了 AtomMonitor。事实上,随着时间的推移,我发现我的应用程序创建的 RWM Atom 数量越来越多(几天后大约有 4000 个)。这适合异常消息。所有字符串如下所示:

C1FE = HwndWrapper[XY.exe;;b68ce81a-d29f-414b-b63a-3b6979e33dd3]  --RWM

从异常消息中,我看到一个“弹出窗口”导致 RegisterClassEx 来自 OnIsOpenChanged 方法。

但是,在我的应用程序中打开和关闭多个弹出窗口并并行监控 RWM 原子的计数,我看不到任何增加,这就是为什么我找不到问题的确切根源。过了一段时间,再次查看统计数据时,我发现计数增加了。

所以我的问题是:

  1. Popup 可以负责提高 RWM 原子的数量吗?如果是,这是一个错误吗?为什么它会创建一个新的Window 并注册这些原子?

  2. 我是否以错误的方式使用Popup?我必须关闭/处置/释放某些东西吗?

  3. Popup 有问题吗?

  4. 应用程序创建或不应超过的“正常”RWM 原子数是多少,因为据我所知,它们不能再被删除。

【问题讨论】:

  • 这个问题可能与 C# 或 WPF 无关。它基于 COM 技术。有点像 .NET 的前身,它有一些额外的问题和限制。我添加了标签来表示它。
  • 请将堆栈翻译成英文。 @Christopher - 你在哪里看到 COM?
  • 仅仅因为调用RegisterClassEx时弹出异常并不意味着该方法对泄漏负责。压垮骆驼的是最后一根稻草(德语:Es war der Tropfen, der das Fass zum Überlaufen brachte)。确保 Dispose 所有一次性对象(显式或使用 using 语句)!
  • @SimonMourier System.ComponentModel.Win32Exception。当我们已经有类似托管的内存不足异常时,“没有足够的存储空间来处理此命令”。所以它绝对与托管代码 OOM 无关。
  • @SimonMourier 我用翻译更新了帖子

标签: c# wpf winapi win32exception


【解决方案1】:

经过一番研究,我发现:它与弹出窗口或任何“真实”窗口无关。除此之外,关闭弹出窗口会释放原子表中的条目。

原因是:我们在不同的任务上创建 WriteableBitmaps 用于图像处理。总是当一个新线程用于此任务(创建 WPF 控件)时,会创建一个 Dispatcher,而后者又会创建一个 HwndWrapper。

如果调度程序没有手动关闭,这些资源不会被释放。现在我们使用以下链接中的解决方法:

GitHub: Win32Exception is thrown when WPF runs out of internal resources

SO: Why does LongRunning task (TPL) with JpegBitmapDecoder run out of resources?

Microsoft Connect: System.ComponentModel.Win32Exception (0x80004005): Not enough storage is available to process this command

SO: Resource leak when creating freezable objects in a background thread

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-07
    • 2018-08-30
    • 2010-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-23
    相关资源
    最近更新 更多