C# Unreferenced objecten blijven in geheugen?

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • ThaStealth
  • Registratie: Oktober 2004
  • Laatst online: 11-09 10:19
Ik heb hier een C# project waarbij een aantal grote controls zitten die een verzameling subobjecten maken, die per aanroep +-15mb geheugen in gebruik nemen.

Helaas zie ik bij het wisselen tussen de controls dat het geheugen niet vrij gemaakt word. Wat dus tot gevolg heeft dat het geheugen binnen de kortste keren vol zit en de applicatie traag gaat reageren.

Wat doe ik:
- Wanneer in het menu op een bepaalde functie gekozen word maak ik een nieuw control aan van dit type en geef een callback methode mee (voor het wisselen van het scherm)
- Ik ken de control toe aan een globale variable
- Ik voeg de control toe aan een panel

Als een nieuw control getoont moet worden:
- Ik verwijder de callback methode uit de control
- Ik ken een nieuw object toe aan de globale variable
- Ik wis alle controls van het panel

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 private void ShowActiveWindow(UserControl newWindow)
        {
            //removes current control and adds a new control
            if ((newWindow.GetType() == typeof (UcAuthenticate))
            {
                if ((_activeWindow != null) && (_activeWindow != newWindow))
                {
                    _activeWindow.ReleaseResources();
                }                                

                _activeWindow = newWindow;
                pnlBodyData.Controls.Clear();
                
                if (_activeWindow != null)
                {
                    pnlBodyData.Controls.Add(_activeWindow);
                }
            }
        }


Wanneer ik AQTime Profiler erop los laat ziet deze ook dat er 0 references zijn naar het object.

Mijn vraag is dus, waarom word het geheugen niet vrij gegeven door de GC?

Hieronder nog een plaatje van AQTime die de references toont naar dit object (die er dus niet zijn):
Afbeeldingslocatie: http://img340.imageshack.us/img340/7624/allocu.png

Mess with the best, die like the rest


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Het .net framework hoeft geheugen niet direct vrij te geven op het moment dat er geen references meer naar zijn. Het kan best zijn dat hij dat pas gaat doen op het moment dat het systeem geen vrij geheugen meer heeft. Je zou eventueel nog wel kunnen proberen om een GC.Collect tussen te voegen.

Een andere valkuil is vaak dat een event handler van de betreffende class nog verwijst naar een actief object, en op dat moment kan de kan het object niet vrijgegeven worden. Er is dan niet een object die een directe reference heeft.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • BoAC
  • Registratie: Februari 2003
  • Laatst online: 18:45

BoAC

Memento mori

Woy schreef op maandag 29 november 2010 @ 15:49:
Het .net framework hoeft geheugen niet direct vrij te geven op het moment dat er geen references meer naar zijn. Het kan best zijn dat hij dat pas gaat doen op het moment dat het systeem geen vrij geheugen meer heeft. Je zou eventueel nog wel kunnen proberen om een GC.Collect tussen te voegen.

Een andere valkuil is vaak dat een event handler van de betreffende class nog verwijst naar een actief object, en op dat moment kan de kan het object niet vrijgegeven worden. Er is dan niet een object die een directe reference heeft.
Dat laatste zou die profiler moeten kunnen zien lijkt mij.

Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
BoAC schreef op maandag 29 november 2010 @ 15:53:
[...]

Dat laatste zou die profiler moeten kunnen zien lijkt mij.
Dat zou je inderdaad wel verwachten ja.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • ThaStealth
  • Registratie: Oktober 2004
  • Laatst online: 11-09 10:19
Ik heb diverse keren geprobeerd met de GC.Collect() functie aan te roepen, om te kijken of het effect had, dit was niet het geval

Mbt het event wat blijft vasthangen, dit heb ik idd ook gehad, en opgelost (de profiler gaf dit aan).
Het probleem treed niet alleen op bij controls die een event meekrijgen, maar ook bij forms die het niet hebben...

Mess with the best, die like the rest


Acties:
  • 0 Henk 'm!

  • yeep
  • Registratie: Juli 2003
  • Laatst online: 12-01 17:45
Hoe lang draait je applicatie al voordat je dit pobleem ziet? De GC werkt met 3 verschillende niveau's (generations). Items uit generation 0 worden meteen gecollect, items uit generation 1 alleen als er niet geheugen vrij komt met collections uit generation 1 en generation 2 pas daarna (voor desktop applicaties dus zelden).
Het kan zijn dat je controls in generation 1 of hoger zitten en dan zal GC.Collect niet veel voor ze doen als de generation 0 collection al genoeg geheugen vrij maakt.

Je kan ook winDBG gebruiken met de SOS plug-in. Er zijn dan commando's om precies erachter te komen welke objecten nog references hebben naar je controls. Check voor hulp op de weblog van Tess Ferrandez op: http://blogs.msdn.com/b/tess/

Acties:
  • 0 Henk 'm!

  • Hillie
  • Registratie: Januari 2000
  • Laatst online: 22:21

Hillie

Poepen = ultieme ontspanning

Woy schreef op maandag 29 november 2010 @ 15:49:
Het .net framework hoeft geheugen niet direct vrij te geven op het moment dat er geen references meer naar zijn. Het kan best zijn dat hij dat pas gaat doen op het moment dat het systeem geen vrij geheugen meer heeft. Je zou eventueel nog wel kunnen proberen om een GC.Collect tussen te voegen.
Ik weet niet hoe dat in C# of .net gaat, maar het actief aanroepen van GC is in mijn ervaring (10 jaar terug java, tegenwoordig specman/e) een relatief dure actie in performance. Voordeel is wel dat je iets meer voorspelbaarheid inbouwt, maar het is niet altijd noodzakelijk. Tegenwoordig zal GC performance in java (en c#) ongetwijfeld beter zijn dan wanneer ik het voor het laatst gebruikte. :)

Liefhebber van schieten en schijten. Ouwehoer en niet-evangelisch atheist.

Daniel36: Dat zeg ik(?) Nee, dat zeg ik niet, je hebt gelijk.


Acties:
  • 0 Henk 'm!

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

Sebazzz

3dp

yeep schreef op vrijdag 03 december 2010 @ 15:23:
Het kan zijn dat je controls in generation 1 of hoger zitten en dan zal GC.Collect niet veel voor ze doen als de generation 0 collection al genoeg geheugen vrij maakt.
Generation 2 is onder andere voor static velden en singletons.

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


Acties:
  • 0 Henk 'm!

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

Ventieldopje

I'm not your pal, mate!

C#:
1
2
3
4
5
if ((_activeWindow != null) && (_activeWindow != newWindow)) 
{
    _activeWindow.Controls.Clear();
    _activeWindow.ReleaseResources(); 
}  


Zou misschien kunnen helpen ;)

[ Voor 33% gewijzigd door Ventieldopje op 03-12-2010 18:23 ]

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

Pagina: 1