Avatar billede Lasse Novice
03. december 2008 - 16:56 Der er 8 kommentarer og
1 løsning

Memory problem

Hej

Jeg har 10 millioner billeder. For hvert billede skal jeg kalde en ekstern dll med billedets HBITMAP - eller Bitmap.GetHBitmap().

Nemt nok taenker jeg:

foreach(string filePath in filePaths)
{
  using(Bitmap bmp = new Bitmap(filePath))
  {
    IntPtr ptr = bmp.GetHBitmap(); // 1

    GetValueFromExternalCall(ptr); // 2
  }
}

Det viser sig desvaerre at (1) bruger hukommelse for HVERT kald. Efter ca. 600 kald er min memory brugt op, og derefter er det kun et spg. om tid foer page file swapping begynder og tilsidst en OutOfMemory exception.

Er der er en anden maade jeg kunne goere det paa?
Avatar billede kalp Novice
03. december 2008 - 17:11 #1
Har du prøvet at kalde bmp.Dispose(); manuelt?
Jeg ved godt using rydder op efter den, men test alligevel.
Er det et uddrag af koden? eller alt i den løkke?
Avatar billede kalp Novice
03. december 2008 - 17:12 #2
ellers sæt dem til null efterfølgende og ved hver 2-300 stk. kald garbage collector manuelt.
Avatar billede Lasse Novice
03. december 2008 - 17:21 #3
Det er alt i loekken.

bmp.Dispose()>> Det var ogsaa et af mine foerste gaet saa derfor proevede jeg foelgende:

using(Bitmap bmp = new Bitmap(filePath))
{
  foreach(string filePath in filePaths)
  {   
    IntPtr ptr = bmp.GetHBitmap(); // 1

    // GetValueFromExternalCall(ptr); // 2
  }
}

og derefter:

int count = 0;

foreach(string filePath in filePaths)
{
  using(Bitmap bmp = new Bitmap(filePath))
  {
    IntPtr ptr = bmp.GetHBitmap(); // 1

    // GetValueFromExternalCall(ptr); // 2
  }

  if(count % 200 = 0)
  {
    GC.Collect();
  }
}

Begge giver samme resultat!!! Bemaerk at jeg IKKE kalder min GetValueFromExternalCall.
Avatar billede Lasse Novice
03. december 2008 - 17:22 #4
ups, der skulle selvfoelgelig staa

if(++count % 200 == 0)
Avatar billede bitmatic Nybegynder
03. december 2008 - 17:30 #5
Kunne du ikke prøve at copy/paste din kode ind i forummet her, i stedet for at skrive det forfra.

Vi kan måske nemmere se fejlene i den faktisk kode, end i noget du har skrevet ind manuelt.
Avatar billede bitmatic Nybegynder
03. december 2008 - 17:48 #6
ok... Det er fordi du ikke får deleted din int pointer.

Importer DeleteObject med:
    [DllImport("gdi32.dll")]
    public static extern int DeleteObject(IntPtr hObject);

Og prøv så med:



foreach(string filePath in filePaths)
{
  using(Bitmap bmp = new Bitmap(filePath))
  {
    IntPtr ptr = bmp.GetHbitmap(); // 1

    GetValueFromExternalCall(ptr); // 2

    DeleteObject(ptr);
  }
}
Avatar billede Lasse Novice
04. december 2008 - 17:11 #7
Det virker!!!

Jeg troede ikke at managed kald kreerede denne slags ting, men man laere hver dag.

Tak. Point => svar.
Avatar billede arne_v Ekspert
05. december 2008 - 02:31 #8
http://msdn.microsoft.com/en-us/library/1dz311e4.aspx

siger:

You are responsible for calling the GDI DeleteObject method to free the memory used by the GDI bitmap object.

(og det dækker nok over at det netop ikke er et managed object men et unmanged object)
Avatar billede bitmatic Nybegynder
05. december 2008 - 10:33 #9
:-)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester