2010-12-07 7 views
0

일부 사진을 RAM으로 복사하려고하는데 메모리 부족 예외가 발생합니다. 이유는 모르겠지만 "정지" ". 그러나 "unfreeze"하는 방법과 이것이 정말로 문제입니까?메모리 부족 예외 C# freezable.freeze

 public void preLoadThread(Object o) 
    { 
     Overlay ov = (Overlay)o; 
     ImageSource tempNext = BitmapConverter(ov.tempPreLoadPathNext); 
     ImageSource tempPrev = BitmapConverter(ov.tempPreLoadPathPrev); 
     tempNext.Freeze(); 
     tempPrev.Freeze(); 
     ov.Dispatcher.Invoke(
      DispatcherPriority.Normal, 
      (Action)delegate() 
      { 
       ov.preLoadedNext = tempNext; 
       ov.preLoadedPrev = tempPrev; 
       ov.preLoadPathNext = ov.tempPreLoadPathNext; 
       ov.preLoadPathPrev = ov.tempPreLoadPathPrev; 
      } 
     ); 
    } 

    public BitmapSource BitmapConverter(String path) 
    { 
     System.Drawing.Bitmap b = null; 
     using (FileStream fs = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Delete | FileShare.ReadWrite)) 
     { 
      try 
      { 
       b = (System.Drawing.Bitmap)System.Drawing.Bitmap.FromStream(fs); 
      } 
      catch (Exception) 
      { 
       GC.Collect(); 
       GC.WaitForFullGCComplete(); 
      } 
      fs.Close(); 
     } 

     if (b == null) 
     { 
      // Error 
      return null; 
     } 

     BitmapSizeOptions options = BitmapSizeOptions.FromEmptyOptions(); 
     BitmapSource bs = null; 
     try 
     { 
      bs = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
       b.GetHbitmap(), 
       IntPtr.Zero, 
       Int32Rect.Empty, 
       options); 
     } 
     catch (Exception) 
     { 
      GC.Collect(); 
      GC.WaitForFullGCComplete(); 
     } 
     return bs; 
    } 
+3

GC.Collect를가 해답이 될 수 없습니다 ... 옵션을 선택하지 않습니다. –

+0

나는이 누출을 고칠 수있는 단서가 없기 때문에 시도 및 오류가 발생했습니다. – Martin

+0

작업하려는 이미지의 크기는 얼마나됩니까? –

답변

0

은 지금까지 당신의 "고정 해제"질문으로, 당신은 내가 진심으로 메모리 예외가 프리즈 (Freeze)에서 오는 의심 details and example at MSDN

1

이 아닌 초기 항목하지만 당신이 고정되지 않은 복제를 분사 할 수 있습니다 () 호출, 정말 메모리를 할당하지 않습니다.

나는 GDI 누출이있을 것이라고 확신한다 ... CreateBitmapSourceFromHBitmap()을 호출 한 후에 생성 한 비트 맵에서 DeleteObject를 호출해야하지만 GetHbitmap()을 매개 변수로 호출하기 때문에 삭제할 핸들이 없습니다.

이 시도 :

[System.Runtime.InteropServices.DllImport("gdi32.dll")] 
public static extern bool DeleteObject(IntPtr hObject); 

... 

IntPtr hObject = b.GetHbitmap(); 
bs = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
      hObject, 
      IntPtr.Zero, 
      Int32Rect.Empty, 
      options); 

DeleteObject(hObject); 


헹크 잘, 당신은 GC 수집을 강요해서는 안 ... 당신이 정말로 수집 할 아무것도 확보하지 있기 때문에 정말 당신을 도움이되지 것, 어쨌든 (해방하는 유일한 것은 DeleteObject()를 통해 정리해야합니다.)

1378x2000 이미지의 수는 무엇입니까? GDI 누수를 해결하더라도 큰 그림이되어 빠르게 메모리를 소모합니다 .

Curtisk가 맞습니다. 고정 해제 할 수 없습니다. 복제해야합니다 ...하지만 그렇게 할 때 메모리를 할당하게 될 것입니다. 그냥 당신에게 경고합니다.

내가 64 비트에서 실행 가정 해 봅시다 것은 catch 블록에서

+0

'DeleteObject() '란 무엇입니까? 참조가 누락 되었습니까? –

+0

'gdi32.dll' DLL (Windows의 일부)에서 호출 선언입니다. 선언 위의 속성은 .NET에 런타임에 해당 DLL을 가져 오도록 지시하고 코드에서 'DeleteObject()'호출을 찾을 위치를 알려줍니다. 경고, 당신은 관리되지 않는 코드를 호출하고 거기에 많은 의미가 있습니다. 추가 정보 링크 : https://msdn.microsoft.com/en-us/library/system.runtime.interopservices.dllimportattribute%28v=vs.110%29.aspx –