Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[Ajax]Applicatie voor 24/7, Geheugen loopt vol.

Pagina: 1
Acties:

  • Glashelder
  • Registratie: September 2002
  • Niet online

Glashelder

Anti Android

Topicstarter
Ik ben bezig met een HTML pagina die van Ajax gebruik maakt. Op deze Ajax pagina zijn een hoop vakken. Elk vak staat voor een klant van ons, en een klant kan weer voor een aantal servers staan. Het systeem is bedoeld om van elke klant de huidige status te kunnen zien (alles goed, harde schijf die vol loopt..mailserver die plat ligt / enz..). Deze pagina staat de hele dag open op een plasma scherm dat hier aan de muur hangt.

Tot een paar weken geleden was dit een pagina die door PHP gegenereerd werd. Elke 10 seconde ging het scherm op wit en werd de boel ververst. Omdat dat heel irritant is, ben ik dus een tijd geleden aan de slag gegaan om hier een Ajax site van te maken. Dan hoeft de boel niet de hele tijd ververst te worden :)

Het probleem is dat na 20 tot 40 minuten het geheugengebruik onwijs toeneemt (van ~22MB tot 70MB, daarna loopt het op tot 500MB++). Duidelijk een geheugenlek dus. IE hoef ik niet eens te proberen want die begint direct het geheugen vol te gooien ;)


Het is een hele lap code, ik zal functie een beetje proberen uit te leggen wat er gebeurd.

Er wordt een lijst met klanten van de server gedownload, en voor elke klant wordt er een div aangemaakt. Daarna wordt voor elke klant de huidige status ongevraagd, en aan de hand daarvan wordt er een bepaalde achtergrond afbeelding voor elke div ingesteld. Dit gaat allemaal goed. Het probleem zit hem in het updaten.

Bij het laden wordt het volgende ingesteld:

JavaScript:
1
setInterval('UpdateAction();',5000);


Het enige wat UpdateAction() doet, is UpdateKlanten() aanroepen.

JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function UpdateKlanten()
    {
    laatstefunctie = "GET_KLANT";
    
    for($i = 0;$i < KlantenLijst.length;$i++)
        {
        ajaxFunction(KlantenLijst[$i]);
        getIASOStatus(KlantenLijst[$i]);
    }

    if(update==0)
        {
        update = 1;
    }
}


Deze roep AjaxFunction aan. Deze functie voert het xmlHTTP request uit, en stuurt het resultaat weer door naar een andere functie:

JavaScript:
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
53
54
55
56
57
58
59
60
61
62
63
function ajaxFunction(klant)
    {
    TotalData = document.getElementById('gegevens');
    TotalData.innterHTML = ontvangenTekens;

    var xmlHttp;
    try
        {
        // Firefox, Opera 8.0+, Safari
        xmlHttp=null;
        xmlHttp=new XMLHttpRequest();
    }
    catch (e)
        {
        // Internet Explorer
        try
            {
            xmlHttp=null;
            xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
        }
        catch (e)
            {
            try
                {
                xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
            }
            catch (e)
                {
                alert("Your browser does not support AJAX!");
                return false;
            }
        }
    }
    xmlHttp.onreadystatechange=function()
        {
        if(xmlHttp.readyState==4)
            {
            if(laatstefunctie=="PullKlantenLijst")
                {
                ProccesKlantenlijst(xmlHttp.responseText);
                addData(xmlHttp.responseText.length);
            }
            else if(laatstefunctie=="GET_KLANT")
                {
                UpdateKlant(xmlHttp.responseText);
                addData(xmlHttp.responseText.length);
            }
            xmlHttp.onreadystatechange = new Function;
        }
    }
    if(klant==undefined)
        {
        xmlHttp.open("GET","AjaxRequest.php",true);
        xmlHttp.send(null);
    }
    else
        {
        klantEncode = escape(klant);
        xmlHttp.open("GET","AjaxRequest.php?klant=" + klantEncode,true);
        xmlHttp.send(null); 
    }
    
}


Het resultaat, wat naar onderstaande functie (UpdateKlant() ) wordt doorgestuurd, ziet er zo uit:

code:
1
Verhuisservice Jan van Otterlo=GOED



JavaScript:
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
53
54
55
56
57
58
59
60
61
62
63
64
function UpdateKlant(klant)
    {
    var TempKlant = new Array();
    TempKlant = klant.split("=");

    if(TempKlant.length!=2)
        {
        //ReportBug("COM_ERROR:\r\n\r\n" + klant + "\r\n" + laatstefunctie);
    }
    else
        {
        if(LaatsteStatus[klant] == undefined)
            {
            LaatsteStatus[klant] = TempKlant[1];
        }

        KlantDiv = document.getElementById(TempKlant[0]);

        if(LaatsteStatus[klant] == TempKlant[1])
            {
            LaatsteStatus[klant] = TempKlant[1];

            if(TempKlant[1] == "GOED")
                {
                KlantDiv.style.backgroundImage  = "url(http://ks-hostmon/ajax/img/goed.png)";
                KlantDiv.style.color = "RGB(255,255,255)";
                }
            else if(TempKlant[1] == "INET_DOWN")
                {
                KlantDiv.style.backgroundImage  = "url(http://ks-hostmon/ajax/img/inet_down.png)";
                KlantDiv.style.color = "RGB(0,0,0)";
            }
            else if(TempKlant[1] == "DISK_LOW")
                {
                KlantDiv.style.backgroundImage  = "url(http://ks-hostmon/ajax/img/schijfruimte.png)";
                KlantDiv.style.color = "RGB(0,0,0)";
            }
            else if(TempKlant[1] == "UNKOWN")
                {   
                KlantDiv.style.backgroundImage  = "url('http://ks-hostmon/ajax/img/onbekend.PNG')";
                KlantDiv.style.color = "RGB(0,0,0)";
            }               
            else if(TempKlant[1] == "FOUT")
                {   
                KlantDiv.style.backgroundImage  = "url('http://ks-hostmon/ajax/img/service.PNG')";
                KlantDiv.style.color = "RGB(255,255,255)";
            }
            else if(TempKlant[1] == "GPRS")
                {   
                KlantDiv.style.backgroundImage  = "url('http://ks-hostmon/ajax/img/gprs.PNG')";
                KlantDiv.style.color = "RGB(0,0,0)";
            }   
            else if(TempKlant[1] == "WINTAX")
                {   
                KlantDiv.style.backgroundImage  = "url('http://ks-hostmon/ajax/img/wintax.png')";
                KlantDiv.style.color = "RGB(0,0,0)";
            }   
            else
                {
                ReportBug("Onbekende status ontvangen => " + TempKlant[1]);
            }
        }
    }
}


Ik vermoed dat het iets te maken heeft met een timeout, dat er daardoor XMLHTTP objecten in het geheugen blijven hangen (oid) en dat daardoor het geheugen volloopt. Vergeet ik iets anders vrij te geven? Ik had ook al geprobeerd om iets met detach() te doen, maar ik kan nergens precies vinden wat het doet en hoe ik het moet gebruiken..

Of..is Ajax gewoon niet geschikt om constant open te laten staan? Iets wat ik zo langerzamerhand begin te vermoeden :)

PV 4915wp op oost, 2680 wp op west, 1900 wp op zuid. pvoutput - AUX 8 kW bi bloc


  • TheDane
  • Registratie: Oktober 2000
  • Laatst online: 23:02

TheDane

1.618

Waarom gebruik je hier niet iets bestaands voor?
Zabbix, Nagios etc zijn prima tools die heel wat meer in de gaten houden dan alleen wat diskspace.

En als diskspace zo belangrijk is .. is 't dan niet tijd voor wat overcapaciteit? Ik kan me niet voorstellen dat je iedere dag moet checken of een server bijna vol aan 't raken is. Of genereren die klanten gigabytes data per dag :?

[ Voor 8% gewijzigd door TheDane op 19-02-2008 15:59 . Reden: linkjes ;) ]


  • Glashelder
  • Registratie: September 2002
  • Niet online

Glashelder

Anti Android

Topicstarter
Omdat er 1) al wat al wat bestaands gebruikt wordt, en 2) er heel wat meer gemonitored wordt dan 'alleen wat diskspace'.

Ik heb niet gekozen voor deze software. Deze software heeft geen mooie front-end om alles in een oogopslag weer te geven. Vandaar deze oplossing. Maargoed daar gaat het niet over :)

PV 4915wp op oost, 2680 wp op west, 1900 wp op zuid. pvoutput - AUX 8 kW bi bloc


  • linksnl
  • Registratie: Februari 2002
  • Niet online
Glashelder schreef op dinsdag 19 februari 2008 @ 14:48:
JavaScript:
48
            xmlHttp.onreadystatechange = new Function;
Waarom staat dit binnen je onreadystatechange functie?

  • MueR
  • Registratie: Januari 2004
  • Laatst online: 01:43

MueR

Admin Devschuur® & Discord

is niet lief

Waarom haal je alle klanten op, en ga je vervolgens per klant een request maken? Met een beetje creatief gebruik van bijvoorbeeld JSON moet je dit ook makkelijk in 1 keer kunnen doen.

Anyone who gets in between me and my morning coffee should be insecure.


  • Johnny
  • Registratie: December 2001
  • Laatst online: 15:26

Johnny

ondergewaardeerde internetguru

In welke browser draait hij op het scherm? Ik zou eerst eens kijken of het zich in een andere browser ook voordoet, en als het niet zo is gewoon die gebruiken voor het scherm.

Aan de inhoud van de bovenstaande tekst kunnen geen rechten worden ontleend, tenzij dit expliciet in dit bericht is verwoord.


  • Tofu
  • Registratie: Maart 2003
  • Laatst online: 05-10-2024
Johnny schreef op dinsdag 19 februari 2008 @ 17:45:
In welke browser draait hij op het scherm? Ik zou eerst eens kijken of het zich in een andere browser ook voordoet, en als het niet zo is gewoon die gebruiken voor het scherm.
Misschien moet de pagina lokaal ook wel te bekijken zijn. Aangezien hij blijkbaar de pagina compatibel wil maken met 4 browsers?

Verwijderd

JavaScript Memory Leak Detector
http://blogs.msdn.com/gpd...memory-leak-detector.aspx

Waarom herbruik je het xmlHttp object niet, nu maak je hem telkens opnieuw aan bij elke call... Maar probeer eerst die mem leak tool...

  • Glashelder
  • Registratie: September 2002
  • Niet online

Glashelder

Anti Android

Topicstarter
MueR schreef op dinsdag 19 februari 2008 @ 17:02:
Waarom haal je alle klanten op, en ga je vervolgens per klant een request maken? Met een beetje creatief gebruik van bijvoorbeeld JSON moet je dit ook makkelijk in 1 keer kunnen doen.
Weet ik eigenlijk niet, ik was ook al aan het kijken om dit te veranderen maar wilde eerst hier even pollen of er iemand een snelle oplossing wist.
Tofu schreef op dinsdag 19 februari 2008 @ 18:29:
[...]

Misschien moet de pagina lokaal ook wel te bekijken zijn. Aangezien hij blijkbaar de pagina compatibel wil maken met 4 browsers?
Hij draaide eerst in IE7, maar die loopt binnen 10 minuten naar 500MB geheugen.. Firefox had dit niet, die begint pas na 20 minuten met vollopen.. Maar hij hoeft maar met een browser te werken.
Verwijderd schreef op dinsdag 19 februari 2008 @ 19:04:
JavaScript Memory Leak Detector
http://blogs.msdn.com/gpd...memory-leak-detector.aspx

Waarom herbruik je het xmlHttp object niet, nu maak je hem telkens opnieuw aan bij elke call... Maar probeer eerst die mem leak tool...
Thx.. zal is kijken. Omdat ik (nog) niet zo heel veel van Javascript weet.. hoe zou ik dat moeten doen?

PV 4915wp op oost, 2680 wp op west, 1900 wp op zuid. pvoutput - AUX 8 kW bi bloc


  • FragFrog
  • Registratie: September 2001
  • Laatst online: 20-11 13:35
Ik heb zelf ooit eens een simpele chat applicatie geschreven die met wat Ajax een keer per seconde ongeveer update. Nauwelijks data, maar als je hem een uurtje open liet staan wel een gigantische aanslag op je geheugen :)

Nu wil ik niet beweren dat het onmogelijk is een AJAX applicatie te maken die dat niet heeft, maar lastig is het soms wel - zeker bij de wat grotere applicaties. Als andere software geen optie is zou je vrij simpel dit soort problemen kunnen afvangen door een complete page refresh die eens per tien minuten oid draait op je pagina te zetten - keurig elke paar seconden een AJAX update en eens in de zoveel tijd wordt je geheugen weer netjes leeggegooid.

Er is trouwens ook een hele simpele manier om de irritante 'flikker' tussen pageviews weg te halen in IE:

HTML:
1
2
3
<!-- Sleezy fake AJAX trick: -->
<meta http-equiv="Page-Enter" content="blendTrans(Duration=0.1)">
<meta http-equiv="Page-Exit"  content="blendTrans(Duration=0.1)">


Of zit ik nu het nut van je project weg te halen? :+

[ Site ] [ twitch ] [ jijbuis ]


Verwijderd

Glashelder schreef op dinsdag 19 februari 2008 @ 19:19:
[...]
Thx.. zal is kijken. Omdat ik (nog) niet zo heel veel van Javascript weet.. hoe zou ik dat moeten doen?
Meest eenvoudige oplossing denk ik is om jquery te gebruiken, zat voorbeelden met Ajax calls, dan ben je van dat verhaal af en kan je focussen op de rest van je code...

http://jquery.com/

bijvoorbeeld deze: http://docs.jquery.com/Ajax/load#urldatacallback

Verwijderd

Trouwens, als ik me niet vergis is een simpele page refresh niet voldoende om van het geheugen probleem af te komen, je zult IE daadwerkelijk af moeten sluiten en opnieuw moeten opstarten om het meeste verloren geheugen terug te krijgen.

  • gvanh
  • Registratie: April 2003
  • Laatst online: 02-12-2023

gvanh

Webdeveloper

Verwijderd schreef op dinsdag 19 februari 2008 @ 20:50:
Trouwens, als ik me niet vergis is een simpele page refresh niet voldoende om van het geheugen probleem af te komen, je zult IE daadwerkelijk af moeten sluiten en opnieuw moeten opstarten om het meeste verloren geheugen terug te krijgen.
Ja, dat is mijn ervaring ook. Wat ik verder in een heel andersoortig project heb gevonden over memory-leaks, is dat wanneer je objecten binnen andere functies/objecten "bewaart", dat dat dan memoryleaks oplevert. Dus bijvoorbeeld:
JavaScript:
1
2
3
function MyObject() {
  this.myAjaxTarget = document.getElementById('ajaxtarget');
}


Het is handig om altijd je ajax target bij de hand te hebben, maar levert dus in mijn ervaring memleaks op. Beter is dus om alleen de referentie naar het object op te slaan (in dit geval het id 'ajaxtarget' en steeds wanneer je het object nodig hebt, hem opnieuw te 'pakken'. Maar ik weet niet of deze situatie op jou van toepassing is.

Verder is er in JavaScript een - volgens mij - weinig gebruikte functie "delete()" waarmee je variabelen kan "unsetten", dus vergelijkbaar met PHP's unset() functie. Misschien kun je die eens loslaten op de XML-response die je binnenkrijgt, nadat je hem verwerkt hebt. Ik heb het zelf nooit geprobeerd, maar misschien haalt dat iets uit.

[ Voor 6% gewijzigd door gvanh op 20-02-2008 09:00 ]


  • FragFrog
  • Registratie: September 2001
  • Laatst online: 20-11 13:35
Verwijderd schreef op dinsdag 19 februari 2008 @ 20:50:
Trouwens, als ik me niet vergis is een simpele page refresh niet voldoende om van het geheugen probleem af te komen, je zult IE daadwerkelijk af moeten sluiten en opnieuw moeten opstarten om het meeste verloren geheugen terug te krijgen.
Ik heb het zelf alleen getest met Maxthon (IE shell), een gewone refresh fixed het daar inderdaad niet in maar een tab sluiten en een nieuw tab openen wel. Ik ga er vanuit dat daar wel iets mee te doen valt :)

[ Site ] [ twitch ] [ jijbuis ]


Verwijderd

je hebt naast het "new" keyword ook het "delete" keyword, gebruik dat eens...
Pagina: 1