[.NET/C#] MemoryLeak + Page Faults bij WebBrowser

Pagina: 1
Acties:

  • Skate2000
  • Registratie: November 1999
  • Laatst online: 29-12-2024
Met C# .Net (2.0) wil ik een Windowsapplicatie maken, waarin geheel automatisch naar verschillende websites wordt gesurft. Hiervoor heb ik een browsercomponent (WebBrowser) op een form gezet. Met webBrowser1.Navigate("http://www.tweakers.net"); kun je vervolgens de browser naar een bijvoorbeeld Tweakers.net laten gaan. :)

Ik heb een minimal-testcase gemaakt, waarin een form een browser bevat die de verschillende locaties gaat openen. Daarnaast is er een Class die in een aparte thread iedere 5 seconden een event geeft (Ticker.cs), zodat het form (met webbrowser) (Form1.cs) weet dat hij weer iets moet gaan doen.

Mijn probleem is echter dat er bij iedere keer dat de browser iets gaat doen er een stapel Page Faults wordt gegenereerd en dat het geheugengebruik van de applicatie toeneemt. Wanneer de applicatie zo een paar uur staat te draaien is hij zo enorm gegroeit dat het niet goed meer kan zijn.

Wat doe ik verkeerd in mijn applicatie, zodat ik met dit probleem zit? Waarom blijft het geheugen gebruik groeien en waarom krijg ik zoveel Page Faults?

Hier de Ticker-class:
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
class Ticker : EventArgs
{
    //Het event voor het tikken
    public event TickHandler Tick;
    public EventArgs e = null;
    
    //Delegate voor de tik
    public delegate void TickHandler(Ticker n, EventArgs e);
    
    //Boolean om de thread te laten draaien
    private bool runTicker;

    //De thread van het tikken itself
    Thread tickThread;

    public Ticker()
    {
        //Boolean op true en gaan met de thread
        runTicker = true;
        tickThread = new Thread(new ThreadStart(this.goTick));
        tickThread.Start();
    }

    //Iedere 5 seconden "doEventTick" aanroepen,
    //als er Classes op geabonneerd zijn
    private void goTick()
    {
        while (runTicker)
        {
            if (Tick != null)
            {
                doEventTick();
            }

            Thread.Sleep(5000);
        }
    }

    //Een tik uitdelen
    private void doEventTick()
    {
        Tick(this, null);
    }

    //De boolean op false zetten, zodat de thread stopt
    public void stop()
    {
        runTicker = false;
    }
}

Deze class draait een goTick-functie in een aparte thread en triggert zijn Tick-event iedere 5 seconden.

Hier mijn form (partial class omdat VS2005 alle opmaakreut elders neerzet):
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
public partial class Form1 : Form
{
    //Declaraties
    string[] locations;
    int currentpage;
    Ticker klok;
    
    public Form1()
    {
        InitializeComponent();
        
        //Dit is de class met het event wat iedere 5 secs tikt
        klok = new Ticker();
        
        //De huidige pagina is de 0'de uit het rijtje
        currentpage = 0;

        //Dit zijn de plaatsen waar ik heen wil
        locations = new string[] {  "http://www.google.com",
                                    "http://www.tweakers.net",
                                    "http://www.nu.nl",
                                    "http://msdn.microsoft.com"
                                    };
        
        //Een abonnement op het event
        //als hij tikt wordt "klok_Tick" aangeroepen
        klok.Tick += new Ticker.TickHandler(klok_Tick);
    }

    //Als de klok een tik uitdeelt wordt deze functie aangeroepen
    //We navigeren dan de browser naar een locatie uit "locations"
    //We hogen currentpage op
    void klok_Tick(Ticker n, EventArgs e)
    {
        webBrowser1.Navigate(locations[currentpage++]);

        if (currentpage > 3)
            currentpage = 0;
    }

    //Als we het form sluiten zeggen we ons abo op
    //Verder zetten we de boolean op false, zodat de thread ook stopt
    private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    {
        klok.Tick -= new Ticker.TickHandler(klok_Tick);
        klok.stop();
    }
}


Dit alles werkt prima, maar mijn lek is een groot probleem :'(

Wanneer ik de browser wél laad, maar niet navigeer (ik comment "webBrowser1.Navigate(locations[currentpage++]);" uit bijvoorbeeld), dan groeien mijn geheugengebruik en de Page Faults niet. Dus het probleem zit hem in het WebBrowser component, lijkt me?

Ik heb al een hoop verschillende constructies geprobeerd om mijn browser aan te sturen, maar steeds treedt dit probleem op, vandaar deze post.

Wie ziet er een oplossing voor mijn geheugen/PageFault issue?

  • EfBe
  • Registratie: Januari 2000
  • Niet online
Als je naar een andere page navigeert dan is de oude page nog gewoon ingeladen, immers wanneer je 'back' doet op de browser dan ga je terug in de history.

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


  • Skate2000
  • Registratie: November 1999
  • Laatst online: 29-12-2024
Ja, duidelijk. Maar betekent dit dan dat een "internet-sessie" steeds meer geheugen in neemt? Hoe langer je aan het surfen bent, hoe meer RAM? Is er niet een maximum aan?

Verder wordt er in dit voorbeeld gebruik gemaakt van slechts 4 pagina's, dan zou hij toch z'n cache moeten overschrijven?

  • EfBe
  • Registratie: Januari 2000
  • Niet online
Skate2000 schreef op maandag 31 oktober 2005 @ 13:13:
Ja, duidelijk. Maar betekent dit dan dat een "internet-sessie" steeds meer geheugen in neemt? Hoe langer je aan het surfen bent, hoe meer RAM? Is er niet een maximum aan?

Verder wordt er in dit voorbeeld gebruik gemaakt van slechts 4 pagina's, dan zou hij toch z'n cache moeten overschrijven?
Nee, naar een page navigeren zal opnieuw die page laden. Wellicht uit de cache maar lang niet alle page onderdelen op bv tweakers zijn cacheable (zoals de ads ;)).

Ik kan 1 2 3 geen method/property vinden die de history leegkiepert. Wel staat er bij Navigate dat de nieuwe page duidelijk aan de history wordt toegevoegd. Ik neem dan aan dat dat je memory problem is. Kan natuurlijk ook gewoon nog dat die IE render engine (die gebruikt wordt) lek is.

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


  • crisp
  • Registratie: Februari 2000
  • Laatst online: 00:26

crisp

Devver

Pixelated

De pagina van nu.nl lekt memory in IE. Meer over memory-leaks in IE: http://www.quirksmode.org...5/10/memory_leaks_li.html

Handige tool om memory-leaks in IE te checken: http://www.outofhanwell.com/ieleak/

Overigens zal je zien dat de frontpage van tweakers.net ook een aantal JS to DOM references heeft, maar die worden dmv een unload handler opgeruimt ;)

Kortom: in het algemeen is het gewoon IE brakheid, voornamelijk door de manier waarop ze DOM hebben geimplementeerd en de garbage collector references tussen JS en DOM objecten niet 'kan zien' en dus ook niet kan opruimen. Echter valt daar vaak wel omheen te werken, maar veel webprogrammeurs zijn zich niet bewust van deze problematiek.

[ Voor 79% gewijzigd door crisp op 31-10-2005 18:02 ]

Intentionally left blank


  • Skate2000
  • Registratie: November 1999
  • Laatst online: 29-12-2024
Kijk! :) Dat zijn berichten waar ik wat aan heb! Ik heb overigens nog even verder zitten pielen. Als ik een javascript toevoeg aan een aantal pagina's, zodat IE ook zelf blijft navigeren, dan heb ik hetzelfde probleem. Het geheugen groeit en de pagefaults ook.

Waarschijnlijk is het geheel dus aan IE te wijten. Een oplossing die ik nu ga implementeren is het wegkieperen van mijn browser en hem opnieuw aanmaken. Dan ben ik één keer van alle onzin af.

De reden dat ik overgens IE gebruik en niet iets als een FF / Mozilla component is dat het al standaard aanwezig is, en een aantal MS-only mogelijkheden heeft, die in deze toepassing van belang zijn. Natuurlijk ben ik me wel bewust van de DOM-brakheid van IE en dat alles speciaal aangepast moet worden voor IE (hopen dat 7 beter wordt ;)) Maar in dit geval maak ik dus specifiek gebruik van eigenschappen van IE. :7

Dank jullie voor de hulp!
Pagina: 1