[C#] Bitmap blijft eeuwig in het geheugen

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • _Thanatos_
  • Registratie: Januari 2001
  • Laatst online: 05-09 14:39

_Thanatos_

Ja, en kaal

Topicstarter
Ik heb een appje gebouwd waarin een behoorlijk grote bitmap gemaakt wordt en na opslaan vervolgens niet meer nodig is. Dan moet ie ook het geheugen uit, maar dat gebeurt niet. De bitmap is in het geheugen meer dan 1GB groot, en bij een tweede keer zo'n ding processen staat het geheugengebruik volgens de task manager al boven de 2GB voor mijn app. En op 3GB bij de derde keer.

Die bitmap gaat dus het geheugen niet uit, terwijl ik er al lang en breed niets meer mee doe.

Wat heb ik al geprobeerd:
  • Een using-clause gebruikt, ongeveer zo:
    C#:
    1
    2
    3
    
    using (Bitmap result = new Bitmap(...)) {
      ...
    }
  • Dispose() aanroepen op de bitmap
  • GC.Collect() aanroepen
Waarom wil dat ding niet weg? Wat is de juiste en/of een betrouwbare manier om een bitmap vrij te geven?

日本!🎌


Acties:
  • 0 Henk 'm!

  • Ventieldopje
  • Registratie: December 2005
  • Laatst online: 17-09 10:59

Ventieldopje

I'm not your pal, mate!

Hoe laad je de bitmap, via een stream, via een pad, via een kabouter, via achmed om de hoek of ..? Opzich zou je code kunnen werken en het enige wat ik me kan bedenken is dat je de filestream die gebruikt wordt niet gesloten wordt waardoor er dingen blijven steken.

www.maartendeboer.net
1D X | 5Ds | Zeiss Milvus 25, 50, 85 f/1.4 | Zeiss Otus 55 f/1.4 | Canon 200 f/1.8 | Canon 200 f/2 | Canon 300 f/2.8


Acties:
  • 0 Henk 'm!

  • oeLangOetan
  • Registratie: Maart 2002
  • Laatst online: 06-08 17:19
Hetgeen je in de taskmanager ziet is de hoeveelheid geheugen je garbage collector voor je applicatie gereserveerd heeft, niet de daadwerkelijke hoeveelheid geheugen dat je applicatie gebruikt.

Acties:
  • 0 Henk 'm!

  • roy-t
  • Registratie: Oktober 2004
  • Laatst online: 08-09 11:33
Als je je applicatie afsluit, wat gebeurt er dan?

Verder: http://arstechnica.com/phpbb/viewtopic.php?f=20&t=65406

bitmap.Dispose() zou dus genoeg moeten zijn, maar dat doet using(){} impliciet al dacht ik.

[ Voor 62% gewijzigd door roy-t op 28-11-2010 11:14 ]

~ Mijn prog blog!


Acties:
  • 0 Henk 'm!

  • _Thanatos_
  • Registratie: Januari 2001
  • Laatst online: 05-09 14:39

_Thanatos_

Ja, en kaal

Topicstarter
Hoe laad je de bitmap
Gewoon zo:
C#:
1
Bitmap result = new Bitmap(20000, 20000);
Hetgeen je in de taskmanager ziet is de hoeveelheid geheugen je garbage collector voor je applicatie gereserveerd heeft, niet de daadwerkelijke hoeveelheid geheugen dat je applicatie gebruikt.
Kan zijn, maar dat getalletje in de task manager blijft ophogen, en Windows gaat het geheugen voor andere applicaties naar de pagefile trappen. Dus of dat geheugen nou gebruikt wordt of niet, boeit me niet, het is voor die ene executable gereserveerd en die heeft het niet meer nodig. Als de app het echt *nodig* zou hebben, dan heb je gelijk, maar iedere nieuwe bitmap neemt evenzoveel geheugen in beslag, terwijl ie net zo goed het blok geheugen van de vorige bitmap had kunnen overschrijven.
Als je je applicatie afsluit, wat gebeurt er dan?
Ja, dan is het weg natuurlijk |:(
Als een executable ophoudt met bestaan, dan houden z'n resources ook op met bestaan. Wat dacht je dan dat er ging gebeuren??
bitmap.Dispose() zou dus genoeg moeten zijn, maar dat doet using(){} impliciet al dacht ik.
Nou, niet dus... De bitmap blijft gewoon lekker bestaan (hoewel ie voor de applicatie niet meer toegankelijk is - hij wordt in het geheugen niet vrijgegeven dus).

日本!🎌


Acties:
  • 0 Henk 'm!

  • CodeCaster
  • Registratie: Juni 2003
  • Niet online

CodeCaster

Can I get uhm...

Als je elders in je code naar de "result"-bitmap verwijst en dat ernaar verwijzende object blijft bestaan, dan wordt je bitmap natuurlijk ook niet verwijderd.

https://oneerlijkewoz.nl
Op papier is hij aan het tekenen, maar in de praktijk...


Acties:
  • 0 Henk 'm!

  • goldoni
  • Registratie: November 2010
  • Laatst online: 25-11-2024
Met using wordt de dispose aangeroepen en zal het geheugen worden vrijgegeven, tenzij er nog verwijzingen zijn. Misschien is WPF een optie?

Acties:
  • 0 Henk 'm!

  • Sebazzz
  • Registratie: September 2006
  • Laatst online: 16-09 15:42

Sebazzz

3dp

goldoni schreef op zondag 28 november 2010 @ 19:26:
Met using wordt de dispose aangeroepen en zal het geheugen worden vrijgegeven, tenzij er nog verwijzingen zijn. Misschien is WPF een optie?
Waarom zou WPF een optie zijn?

[Te koop: 3D printers] [Website] Agile tools: [Return: retrospectives] [Pokertime: planning poker]


Acties:
  • 0 Henk 'm!

  • Alex)
  • Registratie: Juni 2003
  • Laatst online: 21-08 11:20
Je zou Garbage Collection kunnen forceren en kijken wat dat oplevert?

We are shaping the future


Acties:
  • 0 Henk 'm!

  • Sebazzz
  • Registratie: September 2006
  • Laatst online: 16-09 15:42

Sebazzz

3dp

Alex) schreef op zondag 28 november 2010 @ 19:47:
Je zou Garbage Collection kunnen forceren en kijken wat dat oplevert?
Dat heeft ie blijkbaar al geprobeerd.

Met een testprogramma lukt mij het niet om het gedrag te reproduceren.

Testprogramma:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
namespace GoT.BitmapTestApp {
    using System;
    using System.Drawing;

    internal class Program {
        private static void Main(string[] args) {
            PrintAndPause("Voor bitmap test start.");

            for (;;) {
                CreateAndUseBitmap();

                Console.WriteLine("Nog een keer? (y/n)");
                if (Console.ReadKey().KeyChar != 'y') {
                    break;
                }
            }

            PrintAndPause("Einde van de test");
        }

        private static void CreateAndUseBitmap() {
            PrintAndPause("Voor bitmap using(...){...}");

            using (Bitmap result = new Bitmap(10000, 10000)) {
                PrintAndPause("Na bitmap aanmaken");

                for (int x = 0; x < result.Width / 100; x++) {
                    for (int y = 0; y < result.Height / 1000; y++) {
                        result.SetPixel(x, y, Color.FromArgb(x % 255, Math.Abs(255 - y) % 255, Math.Abs(1337 - y) % 255, Math.Abs(299 - (int)(x * 0.5)) % 255));
                    }
                }

                PrintAndPause("Na bitmap verwerken");

                result.Save(
                    System.IO.Path.Combine(
                        Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory),
                        "Test-"+DateTime.Now.GetHashCode()+".png"), System.Drawing.Imaging.ImageFormat.Png);

                PrintAndPause("Na opslaan");
            }

            PrintAndPause("Na bitmap using(..){...}");
        }

        static void PrintAndPause(string msg) {
            Console.WriteLine(msg);

            Console.ReadKey();
        }
    }
}

[Te koop: 3D printers] [Website] Agile tools: [Return: retrospectives] [Pokertime: planning poker]


Acties:
  • 0 Henk 'm!

  • goldoni
  • Registratie: November 2010
  • Laatst online: 25-11-2024
Sebazzz schreef op zondag 28 november 2010 @ 19:30:
[...]

Waarom zou WPF een optie zijn?
managed code....

Acties:
  • 0 Henk 'm!

  • AtleX
  • Registratie: Maart 2003
  • Niet online

AtleX

Tyrannosaurus Lex 🦖

C# is ook managed.

Sole survivor of the Chicxulub asteroid impact.


Acties:
  • 0 Henk 'm!

  • goldoni
  • Registratie: November 2010
  • Laatst online: 25-11-2024
Natuurlijk, maar het bitmap object niet. Daar is alleen een wrapper omheen gebouwd in het .Net framework, vandaar dat je deze in een using of try-cath-finally gebruikt om op te ruimen.

Acties:
  • 0 Henk 'm!

  • Sebazzz
  • Registratie: September 2006
  • Laatst online: 16-09 15:42

Sebazzz

3dp

Dan heb je het dus over unmanaged objects. Maar die heb je sowieso ergens in de pijplijn.

Dan snap ik nog steeds niet wat je met WPF wil, WPF is immers een grafisch subsysteem om userinterfaces te tekenen.

[Te koop: 3D printers] [Website] Agile tools: [Return: retrospectives] [Pokertime: planning poker]


Acties:
  • 0 Henk 'm!

  • CodeCaster
  • Registratie: Juni 2003
  • Niet online

CodeCaster

Can I get uhm...

Hij heeft (afgezien van WPF) wel een punt. Zie: http://msdn.microsoft.com/en-us/library/kwybd81a.aspx

Roep die eens aan met de parameter op true?

https://oneerlijkewoz.nl
Op papier is hij aan het tekenen, maar in de praktijk...


Acties:
  • 0 Henk 'm!

  • Sebazzz
  • Registratie: September 2006
  • Laatst online: 16-09 15:42

Sebazzz

3dp

CodeCaster schreef op zondag 28 november 2010 @ 20:58:
Hij heeft (afgezien van WPF) wel een punt.
Wat is het punt? Dat Bitmap unmanaged GDI+ object gebruikt en daarom voor problemen zorgt?
Roep die eens aan met de parameter op true?
Dat kan niet, hij is protected en Bitmap zelf is een sealed class.

[Te koop: 3D printers] [Website] Agile tools: [Return: retrospectives] [Pokertime: planning poker]


Acties:
  • 0 Henk 'm!

  • CodeCaster
  • Registratie: Juni 2003
  • Niet online

CodeCaster

Can I get uhm...

Ah ja, dat zag ik niet. Daarnaast is de Dispose(boolean) een afzwakking, de gewone Dispose() doet hetzelfde als Dispose(true).

Dan blijf ik bij m'n eerste statement.
Call Dispose when you are finished using the Image. The Dispose method leaves the Image in an unusable state. After calling Dispose, you must release all references to the Image so the garbage collector can reclaim the memory that the Image was occupying. For more information, see Cleaning Up Unmanaged Resources and Implementing a Dispose Method.

https://oneerlijkewoz.nl
Op papier is hij aan het tekenen, maar in de praktijk...


Acties:
  • 0 Henk 'm!

  • sig69
  • Registratie: Mei 2002
  • Laatst online: 03:43
Wat is eigenlijk je probleem? Dat vermeldt je nergens. Hoeveel geheugen heeft de machine waar je dit op draait? Het disposen van een object betekent namelijk niet dat het geheugen meteen vrijgegeven wordt.

Roomba E5 te koop


Acties:
  • 0 Henk 'm!

  • Sebazzz
  • Registratie: September 2006
  • Laatst online: 16-09 15:42

Sebazzz

3dp

CodeCaster schreef op zondag 28 november 2010 @ 21:33:

Dan blijf ik bij m'n eerste statement.

[...]
Maar de TS heeft using ook geprobeerd, en als je using op de manier als in de TS gebruikt dan zijn na het 'afsluiten' van de using ook alle referenties naar het Bitmap object verloren.

[Te koop: 3D printers] [Website] Agile tools: [Return: retrospectives] [Pokertime: planning poker]


Acties:
  • 0 Henk 'm!

  • CodeCaster
  • Registratie: Juni 2003
  • Niet online

CodeCaster

Can I get uhm...

Sebazzz schreef op zondag 28 november 2010 @ 21:47:
[...]
Maar de TS heeft using ook geprobeerd, en als je using op de manier als in de TS gebruikt dan zijn na het 'afsluiten' van de using ook alle referenties naar het Bitmap object verloren.
Nee hoor.
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
class A
{
    public B B;

}

class B: IDisposable
{
    public String MyB = "B still exists";

    public void Dispose()
    {
        Console.WriteLine("B was Dispose()d");
    }
}

class Program
{
    static void Main(string[] args)
    {

        A a = new A();

        using (B b = new B())
        {
            a.B = b;
        }

        GC.Collect();

        Console.WriteLine(a.B.MyB);

        Console.Read();
    }
}

Geeft:
B was Dispose()d
B still exists


Zolang er ergens nog een referentie naar een object bestaat zal het niet verwijderd worden.

[ Voor 5% gewijzigd door CodeCaster op 28-11-2010 22:09 ]

https://oneerlijkewoz.nl
Op papier is hij aan het tekenen, maar in de praktijk...


Acties:
  • 0 Henk 'm!

  • Sebazzz
  • Registratie: September 2006
  • Laatst online: 16-09 15:42

Sebazzz

3dp

CodeCaster schreef op zondag 28 november 2010 @ 22:07:
[...]

Nee hoor.
Zolang er ergens nog een referentie naar een object bestaat zal het niet verwijderd worden.
Ik nam aan dat de TS dat soort dingen niet deed ;)

[Te koop: 3D printers] [Website] Agile tools: [Return: retrospectives] [Pokertime: planning poker]


Acties:
  • 0 Henk 'm!

  • CodeCaster
  • Registratie: Juni 2003
  • Niet online

CodeCaster

Can I get uhm...

Ik denk dat we hier zonder verdere code weinig over kunnen zeggen, TS zal niet de eerste zijn die het Bitmap-object gebruikt dus een bug in de Dispose() of Finalize() hiervan acht ik onwaarschijnlijk.

Ik vermoed dus dat TS zijn bitmap-object nog doorgeeft aan andere object(en), en dat in die klasse de verwijzing niet netjes wordt opgeruimd.

[ Voor 224% gewijzigd door CodeCaster op 28-11-2010 22:33 ]

https://oneerlijkewoz.nl
Op papier is hij aan het tekenen, maar in de praktijk...


Acties:
  • 0 Henk 'm!

  • Sebazzz
  • Registratie: September 2006
  • Laatst online: 16-09 15:42

Sebazzz

3dp

Ja, maar ik neem aan dat de referenties van die klasse na het using statement ook weer verdwenen zijn ;)

[Te koop: 3D printers] [Website] Agile tools: [Return: retrospectives] [Pokertime: planning poker]


Acties:
  • 0 Henk 'm!

  • goldoni
  • Registratie: November 2010
  • Laatst online: 25-11-2024
De opmerking over WPF heeft ermee te maken dat TS zegt dat er "een behoorlijk grote bitmap" gemaakt wordt. Dit zou ook kunnen met het grafisch subsysteem van WPF etc. Maar ik ben het met CodeCaster eens dat zonder code het nu een raadspelletje wordt. ;)
Maar de conclusie is wel dat er nog een referentie naar het object is....

Acties:
  • 0 Henk 'm!

  • roy-t
  • Registratie: Oktober 2004
  • Laatst online: 08-09 11:33
_Thanatos_ schreef op zondag 28 november 2010 @ 17:55:
Ja, dan is het weg natuurlijk |:(
Als een executable ophoudt met bestaan, dan houden z'n resources ook op met bestaan. Wat dacht je dan dat er ging gebeuren??
Unmanaged resources worden ook niet door de GC opgeruimd, maar worden ook niet opgeruimd als je de applicatie afsluit (niet altijd waar). Dus nu weten we dat het niet een unmanaged resource is die blijft hangen.

~ Mijn prog blog!


Acties:
  • 0 Henk 'm!

  • jmzeeman
  • Registratie: April 2007
  • Laatst online: 12-09 16:17
roy-t schreef op maandag 29 november 2010 @ 09:24:
[...]


Unmanaged resources worden ook niet door de GC opgeruimd, maar worden ook niet opgeruimd als je de applicatie afsluit (niet altijd waar). Dus nu weten we dat het niet een unmanaged resource is die blijft hangen.
offtopic:
Wat voor unmanaged resources worden niet automatisch opgeruimd bij een process exit dan? Het enige wat ik kan bedenken is een tempfile wat niet gedelete wordt of vage 3rd party dingen. Maar alle kernel objecten worden gerefcount, GDI(+) objecten zijn private in een process en al het geheugen van een process wordt vrijgegeven bij het sluiten van het process. Zou een mooie bende worden als elk niet .NET process dat crashed z'n resources niet vrijgeeft.

[ Voor 7% gewijzigd door jmzeeman op 29-11-2010 14:20 ]


Acties:
  • 0 Henk 'm!

  • Kickasz
  • Registratie: April 2003
  • Niet online
Ik heb even een voorbeeld in elkaar gezet, maar in C# (3.5) krijg ik het niet werkend hoor ;).

code:
1
2
3
4
5
6
7
8
9
10
11
private void LoadPicture()
        {
            Bitmap bitmap;
            
            using (Bitmap result = new Bitmap(400, 400))
            {
                  bitmap = result;
            }

            pictureBox1.Image = bitmap;
        }


Ik krijg dan namelijk de volgende error: "Parameter is not valid.", tijdens het opstarten van de app :P. Niet echt een duidelijk melding, maar het ik krijg het dus niet voor elkaar om een object aan te spreken wat al is opgeruimd _/-\o_ .

Acties:
  • 0 Henk 'm!

  • yade
  • Registratie: Mei 2002
  • Laatst online: 16-07 13:47
Je moet hem dan ook eerst referencen voordat je hem disposed, en daarna de reference gebruiken. Het is allemaal vrij logisch. :P

Acties:
  • 0 Henk 'm!

  • PiepPiep
  • Registratie: Maart 2002
  • Laatst online: 18-01-2023
code:
1
2
3
4
5
6
7
8
9
10
11
private void LoadPicture()
        {
            Bitmap bitmap;
            
            using (Bitmap result = new Bitmap(400, 400))
            {
                  bitmap = result;

                  pictureBox1.Image = bitmap;
            }
        }

Wat doet ie zo?

486DX2-50 16MB ECC RAM 4x 500MB Drive array 1.44MB FDD MS-Dos 6.22


Acties:
  • 0 Henk 'm!

  • Kickasz
  • Registratie: April 2003
  • Niet online
yade schreef op maandag 29 november 2010 @ 16:04:
Je moet hem dan ook eerst referencen voordat je hem disposed, en daarna de reference gebruiken. Het is allemaal vrij logisch. :P
Ondanks dat het vrij logisch is, krijg ik ook op de bovenstaande manier gewoon dezelfde foutmelding als voorheen. Dus als de TS zijn code zou kunnen laten zien, zou het een allemaal een stuk duidelijker kunnen worden voor ons om te helpen .

Acties:
  • 0 Henk 'm!

  • _Thanatos_
  • Registratie: Januari 2001
  • Laatst online: 05-09 14:39

_Thanatos_

Ja, en kaal

Topicstarter
Alle references naar de bitmap zijn volgens mij ook weg. Ik maak em aan, teken er wat op de Graphics, sla em op en geef em (al dan niet geforceerd) vrij. Maar nu ik er zo over denk... zou het Graphics object er niet iets mee te maken hebben? Wellicht dat die een reference vasthoudt?
Unmanaged resources worden ook niet door de GC opgeruimd, maar worden ook niet opgeruimd als je de applicatie afsluit (niet altijd waar).
Unmanaged objecten (handles eigenlijk) worden ALTIJD door het OS opgeruimd zodra het process dat er eigenaar van is, ophoudt met bestaan. Anders zou het OS een geheugenlek hebben, maar dat is in deze niet aan de orde.
Hoeveel geheugen heeft de machine waar je dit op draait?
Het maakt niet uit hoeveel geheugen de machine heeft. Het is voldoende. Het is gewoon flauwekul om geheugen nooit vrij te geven, OOK AL heeft de machine daar voldoende capaciteit voor.
Het disposen van een object betekent namelijk niet dat het geheugen meteen vrijgegeven wordt
In dit geval betekent het dat de bitmap *nooit* vrijgegeven wordt. Zelfs niet na geforceerde garbage collection.

日本!🎌


Acties:
  • 0 Henk 'm!

  • jmzeeman
  • Registratie: April 2007
  • Laatst online: 12-09 16:17
Ben je je niet blind aan het staren op het Bitmap object terwijl het daadwerkelijke probleem ergens anders zit? Als het Bitmap object gedisposed wordt, wordt al zijn unmanaged data vrijgegeven ongeacht of er nog referenties naar toe zijn. Dat er dan nog een paar bytes van de managed wrapper niet worden opgeruimd is niet het probleem.
Zoals jezef al aangeeft gebruik je ook nog een Graphics object. Heb je al geprobeert je Graphics object te disposen? Kan best zijn dat die op het GDI+ niveau de data vast houd.

Edit:
Even getest en dat lijkt hem inderdaad te zijn.
Testcode:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
List<Bitmap> bmps = new List<Bitmap>();
List<Graphics> bmpgs = new List<Graphics>();
for (int i = 0; i < 5; i++)
{
    using (Bitmap bmp = new Bitmap(20000, 20000, PixelFormat.Format24bppRgb))
    {
        //sla even een referentie op om de GC tegen te houden
        bmps.Add(bmp);
        //teken iets
        for (int x = 0; x < 10000; x += 10)
            for (int y = 0; y < 10000; y += 10)
                bmp.SetPixel(x, y, Color.Red);
        Graphics bmpg = Graphics.FromImage(bmp);
        //sla weer even een referentie op om de GC tegen te houden
        bmpgs.Add(bmpg);
        bmpg.Dispose();
    }
}

Als je regel 16 comment onstaat het probleem, regel 8 heeft geen enkel effect. De ParameterException die sommigen krijgen bij het maken van de bitmap betekend dat GDI om de een of andere reden de bitmap niet kan maken. Aangezien ik deze niet zie als ik hem op x64 draai en maar af en toe op x86 denk ik dat ie dan geen groot genoeg stuk ongefragmenteerd geheugen kan vinden.

Geeft maar weer aan dat het niet voor niks best practice is om alles wat IDisposable geïmplementeerd heeft ook daadwerkelijk te disposen.

Het probleem komt er waarschijnlijk uit voort dat je een GDI bitmap(waar GDI+ weer om heengewrapped is) niet mag deleten als ie in een device context(waar het GDI+ en dus ook het .NET Graphics object omheen gewrapped wordt) geselecteerd is. De reden dat de GDI bitmap niet weg gaat is waarschijnlijk dat GDI+ detecteerd dat je een Bitmap die je niet mag weggooien probeert weg te gooien en hem bewaard tot je hem echt niet meer gebruikt.
zie ook:
DeleteObject

[ Voor 74% gewijzigd door jmzeeman op 30-11-2010 23:44 ]


Acties:
  • 0 Henk 'm!

  • _Thanatos_
  • Registratie: Januari 2001
  • Laatst online: 05-09 14:39

_Thanatos_

Ja, en kaal

Topicstarter
Morgen maar es proberen dan.

Toch raar. Het is toch de taak van zo'n framework om dit soort dingen af te vangen. Het is niet mijn keuze dat iets basaals als een bitmap "unmanaged" is (wat ook nog es een vieze term is). Het forceert ook min of meer dat ieder object dat iets met een IDisposable doet, zelf ook IDisposable moet zijn... Riekt naar een antipatroon.

Gelukkig is het niet (of uitgesteld eigenlijk) vrijgeven van geheugen wel sneller.

[ Voor 18% gewijzigd door _Thanatos_ op 01-12-2010 02:37 ]

日本!🎌


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 16-09 22:43
_Thanatos_ schreef op dinsdag 30 november 2010 @ 16:28:
Het maakt niet uit hoeveel geheugen de machine heeft. Het is voldoende. Het is gewoon flauwekul om geheugen nooit vrij te geven, OOK AL heeft de machine daar voldoende capaciteit voor.
Ik ben het met je eens, maar als je daarover meer controle wilt hebben moet je een ander platform pakken. .NET gaat voor makkelijk, ook al is het dat stiekum toch niet.
Het is niet mijn keuze dat iets basaals als een bitmap "unmanaged" is (wat ook nog es een vieze term is)
Dat komt omdat het hele .NET platform een leaky abstraction is.

[ Voor 21% gewijzigd door farlane op 01-12-2010 09:56 ]

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • alienfruit
  • Registratie: Maart 2003
  • Laatst online: 15-09 16:19

alienfruit

the alien you never expected

Klinkt een beetje als reference counting... De device context gebruikt de bitmap nog dus wordt die ook niet opgeruimd. Oh, oud nieuws :)

[ Voor 7% gewijzigd door alienfruit op 01-12-2010 09:55 ]


Acties:
  • 0 Henk 'm!

  • jmzeeman
  • Registratie: April 2007
  • Laatst online: 12-09 16:17
Het framework vangt ook iets af wat jij fout doet, jij geeft je graphics object niet vrij maar je bitmap wel. Omdat dat een situatie is die niet mag voorkomen op het laagste niveau zorgt GDI+ ervoor dat je interne bitmap handle niet wordt weggehaald (je .NET bitmap object wordt waarschijnlijk gewoon weggehaald). Jij gebruikt twee objecten die IDisposable zijn en je zal dus beide moeten vrijgeven (of genoeg geheugen moeten hebben totdat de GC het voor je doet).
In principe zal elk object dat als veld of property een IDisposable object heeft inderdaad ook IDisposable moeten zijn. Dit is geen anti-pattern maar gewoon een logisch gevolg van het feit dat sommige resources schaars of uniek zijn en snel moeten kunnen worden vrijgegeven. Hetzelfde geld voor Streams die wil je ook als programmeur kunnen vrijgeven om zo te voorkomen dat een file gelocked blijft. Uiteindelijk zal .NET je objecten zelf ook wel opruimen, mits jij geen references meer open laat staan en de GC zijn tijd geeft.
farlane schreef op woensdag 01 december 2010 @ 09:53:
[...]
Dat komt omdat het hele .NET platform een leaky abstraction is.
offtopic:
Leuk stuk over die leaky abstractions trouwens, slaat precies de spijker op z'n kop.

[ Voor 17% gewijzigd door jmzeeman op 01-12-2010 12:05 ]

Pagina: 1