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

[IE] Memory leak door filter:alpha()

Pagina: 1
Acties:

  • tec
  • Registratie: Juni 2001
  • Laatst online: 17-12-2024
Doe ik iets geks in de volgende code waardoor IE (6+7) flink memory gaan leaken? Of is hier een workaround voor? (dit is overigens een testcase, voordat jullie vragen wat het voor nut heeft om zulke divs in de DOM te gooien). De leak stopt als ik filter:alpha verwijder.

HTML:
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
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
        <meta name="description" content="" />
        <meta name="keywords" content="" />
        <title>Leak test IE</title>
    </head>
    <body>
        <script type="text/javascript">
        Leak = {
            
            init:function(e) {
                var btn = document.getElementById("leak");
                    btn.style.cursor = "pointer";
                    btn.onclick = Leak.now;
                    
                var release = document.getElementById("leakRelease");
                    release.style.cursor = "pointer";
                    release.onclick = Leak.release;
            },
            
            now:function(e) {
                var el = document.createElement("div");
                    el.className = "leak";
                    el.style.backgroundColor = "red";
                    el.style.height = "256px";
                    el.style.width = "8096px";
                    el.style.top = "10px";
                    el.style.left = "128px";
                    el.style.filter = "alpha(opacity=30)";
                
                var btn = document.getElementById("leak");
                
                btn.parentNode.appendChild(el);
            },
            
            release:function(e) {
                var elements = document.getElementsByTagName("div");
                for(var i=elements.length;i>=0;i--) {
                    if (elements[i] && elements[i].className == "leak") {
                        elements[i].parentNode.removeChild(elements[i]);
                    }
                }
            }
        }

        window.onload = Leak.init;
        </script>
        
        <div id="leak">ME HUNGRY BROWSER!!! GIVE ME SOME MORE MEMORY!! HAARRRR</div>
        <div id="leakRelease">PUKE ME SOME MEMORY!</div>
    </body>
</html>


Elke keer als er een div aangemaakt wordt die transparant is hapt ie zo een 8 mb aan ram weg (de hoeveelheid hangt samen met de grootte van de div). Erger nog, als ik ze weer verwijder krijg ik mn ram niet meer terug. :/ Pas bij een page refresh krijg ik het ram weer vrij.

Je kunt de code zo copy pasten in een .html file en testen in ie6/7.

[ Voor 0% gewijzigd door BtM909 op 30-08-2007 11:04 ]


  • Snake
  • Registratie: Juli 2005
  • Laatst online: 07-03-2024

Snake

Los Angeles, CA, USA

Geen last van in Vista x32?

Going for adventure, lots of sun and a convertible! | GMT-8


  • tec
  • Registratie: Juni 2001
  • Laatst online: 17-12-2024
Geen idee, dit doet zich hier voor op XPSP2

  • .Johnny
  • Registratie: September 2002
  • Laatst online: 27-10 11:50
Ik heb het net ook getest, en ook op Vista x32 gebeurt dit, net als XP SP2 (allebei IE7)
Bij mij gaat ie ongeveer 9 a 11MB. Waarschijnlijk heeft ie dat geheugen nodig om op de plek van de transparente div te kunnen renderen. De browser verwerkt je DIV dan als een bitmap (er moet flink gerenderd worden) of iets dergelijks. Dan zou de grootte goed kunnen verklaren, maar ik weet het ook niet precies.
Dat ze niet weggaan als je de DIV weer weghaalt is overigens inderdaad niet goed.

  • TeeDee
  • Registratie: Februari 2001
  • Laatst online: 30-11 19:45

TeeDee

CQB 241

En als je "el.style.width = "8096px";" eens wat minder maakt?
Beter lezen, dat is van elkaar afhankelijk.

[ Voor 29% gewijzigd door TeeDee op 29-08-2007 14:49 ]

Heart..pumps blood.Has nothing to do with emotion! Bored


  • Padschild
  • Registratie: September 2004
  • Laatst online: 28-11-2020
Probeer eerst een netjes de filter: weg te halen uit CSS, dus even op "" setten. Gebeurt dan hetzelfde?

  • .Johnny
  • Registratie: September 2002
  • Laatst online: 27-10 11:50
Een manier om van een groot gedeelte van de leak af te komen, is door eerst elk element dat je weer weg gaat halen 1x1 pixel breed te maken, en vervolgens de elementen te deleten. Je moet dat wel met een settimeout doen, omdat het anders niet werkt (browser moet eerst de nieuwe omvang verwerken en dat geheugen vrijgeven).

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
(...)
            release:function(e) {
                var elements = document.getElementsByTagName("div");
                for(var i=elements.length;i>=0;i--) {
                    if (elements[i] && elements[i].className == "leak") {
                        elements[i].style.height='1px';
                        elements[i].style.width='1px';
                    }
                }
                setTimeout('Leak.delete_divs()',1)
            },
            
            delete_divs:function() {
                var elements = document.getElementsByTagName("div");
                for(var i=elements.length;i>=0;i--) {
                    if (elements[i] && elements[i].className == "leak") {
                        elements[i].parentNode.removeChild(elements[i]);
                    }
                }
            }


de filter op leeg zetten heeft geen zin, ik vond het wel interessant en heb wat zitten spelen, maar zelfs als je de genoemde alpha filter in een CSS class definieert en de class verandert, blijft het geheugen bezet.

[ Voor 12% gewijzigd door .Johnny op 29-08-2007 15:12 ]


  • tec
  • Registratie: Juni 2001
  • Laatst online: 17-12-2024
.Johnny schreef op woensdag 29 augustus 2007 @ 15:04:
Een manier om van een groot gedeelte van de leak af te komen, is door eerst elk element dat je weer weg gaat halen 1x1 pixel breed te maken, en vervolgens de elementen te deleten. Je moet dat wel met een settimeout doen, omdat het anders niet werkt (browser moet eerst de nieuwe omvang verwerken en dat geheugen vrijgeven).

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
(...)
            release:function(e) {
                var elements = document.getElementsByTagName("div");
                for(var i=elements.length;i>=0;i--) {
                    if (elements[i] && elements[i].className == "leak") {
                        elements[i].style.height='1px';
                        elements[i].style.width='1px';
                    }
                }
                setTimeout('Leak.delete_divs()',1)
            },
            
            delete_divs:function() {
                var elements = document.getElementsByTagName("div");
                for(var i=elements.length;i>=0;i--) {
                    if (elements[i] && elements[i].className == "leak") {
                        elements[i].parentNode.removeChild(elements[i]);
                    }
                }
            }


de filter op leeg zetten heeft geen zin, ik vond het wel interessant en heb wat zitten spelen, maar zelfs als je de genoemde alpha filter in een CSS class definieert en de class verandert, blijft het geheugen bezet.
Allright! :) Dat is iig iets, alleen jammer dat die timeout nodig is.. maargoed dat valt er wel in te beunen. Thanks!

  • .Johnny
  • Registratie: September 2002
  • Laatst online: 27-10 11:50
Dat kun je heel simpel oplossen. Maak gewoon een trash can aan:
<div id="trashcan" style="display: none;"></div>

en in je code verplaats je alles dat geresized is naar die div. In de timeout maak je alleen die div leeg:
code:
1
2
3
4
5
6
7
8
9
10
11
12
(...)
            release:function(e) {
                var elements = document.getElementsByTagName("div");
                for(var i=elements.length;i>=0;i--) {
                    if (elements[i] && elements[i].className == "leak") {
                        elements[i].style.height='1px';
                        elements[i].style.width='1px';
                        document.getElementById('trashcan').appendChild(elements[i]);
                    }
                }
                setTimeout('document.getElementById(\'trashcan\').innerHTML=\'\'',1)
            }

  • .Johnny
  • Registratie: September 2002
  • Laatst online: 27-10 11:50
Strike that. Die laatste post zal je memory leak niet oplossen omdat je in 1 thread de DIVs eerst klein maakt en daarna naar een onzichtbare DIV verplaatst. Dat zal je geheugen niet vrijgeven, of je moet aan het begin je trashcan wel heel even display geven:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
(...)
            release:function(e) {
                var elements = document.getElementsByTagName("div");
                document.getElementById('trashcan').style.display='';//make trashcan visible
                for(var i=elements.length;i>=0;i--) {
                    if (elements[i] && elements[i].className == "leak") {
                        elements[i].style.height='1px';
                        elements[i].style.width='1px';
                        document.getElementById('trashcan').appendChild(elements[i]);
                    }
                }
                setTimeout("document.getElementById('trashcan').innerHTML='';document.getElementById('trashcan').style.display='none';",1)
            }

  • BasieP
  • Registratie: Oktober 2000
  • Laatst online: 19-10 08:18
nog een update:
hij leaked niet echt tenminste neit bij mij (win2k SP4 IE6)

hij doet braaf wat jij zegt (8 mb per divje, en wordt neit opgeruimt als je divjes verwijderd) maar zodra je ergens bij 90 MB komt dan ruimt ie opeens wel op, en zit ik weer aan 20.

my guess is dan ook dat ze in IE ze niet direct geheugen vrijmaken, maar pas als aan bepaalde criteria wordt voldaan (bijv te weinig geheugen vrij, of object langer verwijderd dan .. )

This message was sent on 100% recyclable electrons.


  • Padschild
  • Registratie: September 2004
  • Laatst online: 28-11-2020
BasieP schreef op donderdag 30 augustus 2007 @ 09:40:
nog een update:
hij leaked niet echt tenminste neit bij mij (win2k SP4 IE6)

hij doet braaf wat jij zegt (8 mb per divje, en wordt neit opgeruimt als je divjes verwijderd) maar zodra je ergens bij 90 MB komt dan ruimt ie opeens wel op, en zit ik weer aan 20.

my guess is dan ook dat ze in IE ze niet direct geheugen vrijmaken, maar pas als aan bepaalde criteria wordt voldaan (bijv te weinig geheugen vrij, of object langer verwijderd dan .. )
Bij mij werd het naar de pagefile weggeschreven... Die groeide echt gigantisch veel, terwijl er aan het proces niet echt meer memory werd toegevoegd. Ik heb echt honderd keer geklikt en na verloop van tijd wordt alles toch wel een beetje traag...

  • tec
  • Registratie: Juni 2001
  • Laatst online: 17-12-2024
Ik heb het bovenstaande nu ook geconstateerd.. Als ie teveel mem pakt en je verwijderd de divs dan, dan geeft ie het gepikte geheugen wel weer terug. Niet geweldig, maar voldoende.

  • .Johnny
  • Registratie: September 2002
  • Laatst online: 27-10 11:50
Bij mij geeft ie in dat geval maar ongeveer de helft terug...

edit; nog eens gekeken, maar de hoeveelheid die je dan terug krijgt lijkt volstrekt random te zijn. Je moet trouwens de stappen wat groter maken om dit snel te testen (for loopje en 10 divs tegelijk aanmaken per klik, of ze gewoon groter maken)

[ Voor 67% gewijzigd door .Johnny op 30-08-2007 13:35 ]


  • SchizoDuckie
  • Registratie: April 2001
  • Laatst online: 18-02 23:12

SchizoDuckie

Kwaak

Er is een ongedocumenteerde functie CollectGarbage(); in IE. Helpt die nog?

Stop uploading passwords to Github!

Pagina: 1