cefsharp / CefSharp

.NET (WPF and Windows Forms) bindings for the Chromium Embedded Framework
http://cefsharp.github.io/
Other
9.89k stars 2.92k forks source link

Storage limit exception #525

Closed Bodekaer closed 9 years ago

Bodekaer commented 10 years ago

I just got this exception. {"Not enough storage is available to process this command. (Exception from HRESULT: 0x80070008)"}

Honestly not sure what to do about it, but some sort of exception handling might be a good step. It happened when I was very actively using CEFSharp, opening and closing many browsers (max 8 at a time though). Also I have plenty of free disk space :)

Here is the stack trace. Hope it's helpful to someone here :)

  at System.Windows.Interop.InteropBitmap..ctor(IntPtr section, Int32 pixelWidth, Int32 pixelHeight, PixelFormat format, Int32 stride, Int32 offset)
  at System.Windows.Interop.Imaging.CreateBitmapSourceFromMemorySection(IntPtr section, Int32 pixelWidth, Int32 pixelHeight, PixelFormat format, Int32 stride, Int32 offset)
  at CefSharp.Wpf.ChromiumWebBrowser.SetBitmapHelper(BitmapInfo bitmapInfo, InteropBitmap bitmap, Action`1 imageSourceSetter) in c:\Users\Bodekaer\GitHub\CefSharp\CefSharp.Wpf\ChromiumWebBrowser.cs:line 1210
  at CefSharp.Wpf.ChromiumWebBrowser.CefSharp.Internals.IRenderWebBrowser.SetBitmap(BitmapInfo bitmapInfo) in c:\Users\Bodekaer\GitHub\CefSharp\CefSharp.Wpf\ChromiumWebBrowser.cs:line 1187
  at CefSharp.Wpf.ChromiumWebBrowser.<>c__DisplayClassf.<CefSharp.Internals.IRenderWebBrowser.InvokeRenderAsync>b__e() in c:\Users\Bodekaer\GitHub\CefSharp\CefSharp.Wpf\ChromiumWebBrowser.cs:line 644
  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)
  at System.Windows.Threading.DispatcherOperation.InvokeImpl()
  at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state)
  at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
  at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
  at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
  at System.Windows.Threading.DispatcherOperation.Invoke()
  at System.Windows.Threading.Dispatcher.ProcessQueue()
  at System.Windows.Threading.Dispatcher.WndProcHook(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)
  at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
  at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
  at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
  at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
  at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
  at System.Windows.Threading.Dispatcher.Run()
  at System.Windows.Application.RunDispatcher(Object ignore)
  at System.Windows.Application.RunInternal(Window window)
  at System.Windows.Application.Run(Window window)
  at System.Windows.Application.Run()
jankurianski commented 10 years ago

@Bodekaer I've seen this type of exception in my own C# apps when using Win32 APIs and the process is out of memory. Were you running in 32-bit mode?

Bodekaer commented 10 years ago

Yes, also 32-bit more here.

amaitland commented 10 years ago

Possible that we have a memory leak with the bitmap generation.

amaitland commented 10 years ago

Having poked around a bit in the rendering side of things yesterday the stacktrace means a little more than it did before :smile:

https://github.com/cefsharp/CefSharp/blob/master/CefSharp.Wpf/ChromiumWebBrowser.cs#L1230

Couple of follow up questions

amaitland commented 10 years ago

It doesn't look like we explicitly close the file handlers used for the InteropBitmap.

https://github.com/cefsharp/CefSharp/blob/master/CefSharp.Core/Internals/RenderClientAdapter.h#L189

I would think they should be cleaned up during Dispose of a browser.

@Bodekaer How much effort is involved to reproduce this issue?

amaitland commented 10 years ago

I've pushed a change to 2171 https://github.com/cefsharp/CefSharp/commit/d38118393b9e698ebc37316130eb0d6bf0359eca

Perhaps if you've got a minute you could take it for a spin?

amaitland commented 9 years ago

@Bodekaer Are you still seeing this problem with the latest 2171 branch?

Bodekaer commented 9 years ago

Nope. Haven't seen it for over a month, so I think it's done.

amaitland commented 9 years ago

Excellent! Not really surprised it was leaking, the handlers were never being released.

mol commented 8 years ago

We're again seeing this happen in Mailbird for a good number of users. The stack trace is almost the same (following below). The odd thing is the PrivateMemorySize64 for the process (which is still forced 32-bit) is around 450 MB, which is high, but from what I understand shouldn't have hit any limit? The 'GC.GetTotalMemory(false) is just 82 MB if that has any bearing on anything.

System.Runtime.InteropServices.COMException (0x80070008): Not enough storage is available to process this command. (Exception from HRESULT: 0x80070008) 
at System.Windows.Interop.InteropBitmap..ctor(IntPtr section, Int32 pixelWidth, Int32 pixelHeight, PixelFormat format, Int32 stride, Int32 offset) 
at System.Windows.Interop.Imaging.CreateBitmapSourceFromMemorySection(IntPtr section, Int32 pixelWidth, Int32 pixelHeight, PixelFormat format, Int32 stride, Int32 offset) 
at CefSharp.Wpf.Rendering.InteropBitmapInfo.CreateBitmap() 
at CefSharp.Wpf.ChromiumWebBrowser.<>c__DisplayClasse.<CefSharp.Internals.IRenderWebBrowser.InvokeRenderAsync>b__d() 
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs) 
at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
mol commented 8 years ago

@amaitland should I be creating a new issue or? I'm not seeing a re-open button. FYI @Antonyo in case you reported this elsewhere - let me know.

mol commented 8 years ago

It's pretty easy to reproduce this and the OutOfMemoryException that can also occur there if making a few modifications to account for the user using a 4k resolution and 400% scaling in Windows that should be relatively common for 4k users.

This leaves WriteableBitmapInfo.CreateBitmap to potentially run 'new WriteableBitmap' with something like these values:

Bitmap = new WriteableBitmap(3840, 2160, 384, 384, Bgra32, null);

It's not enough with one control, but have a few of them and resize them all at the same time and it will crash.

amaitland commented 8 years ago

The odd thing is the PrivateMemorySize64 for the process (which is still forced 32-bit) is around 450 MB, which is high, but from what I understand shouldn't have hit any limit?

If you haven't already you should set largeaddressaware on your exe

The 'GC.GetTotalMemory(false) is just 82 MB if that has any bearing on anything.

The buffer is copied into unmanaged memory (part of the page file if I remember correctly).

@amaitland should I be creating a new issue?

If you like. I don't have time to look into this, so would be purely for tracking of your progress.