...

View Full Version : Global variables vs. Expando attributes



swmr
05-06-2004, 01:34 AM
Would there be a difference in memory between storing data in a global variable and setting data as an arbitrary attribute?

For example, comparing these two functions:

<html>
<head>
<title>-</title>

<script type="text/JavaScript">

var mousedown;

function _Global(){
if(mousedown){
var o = document.getElementById("output");
o.value = "_Global: dragging";}
}

function _Expando(Mousedown){
if(Mousedown){
var o = document.getElementById("output");
o.value = "_Expando: dragging";}
}

</script>

</head>
<body
onload="document.getElementsByTagName('SPAN')[1].setAttributeNode(document.createAttribute('mousedown'))">

<span
onmousedown="mousedown=true"
onmouseup="mousedown=false"
onmouseout="mousedown=false"
onmousemove="_Global()">
[dragMe]
</span>
<input id="output">
<span
onmousedown="this.mousedown=true"
onmouseup="this.mousedown=false"
onmouseout="this.mousedown=false"
onmousemove="_Expando(this.mousedown)">
[dragMe]
</span>

</body>
</html>

swmr
05-06-2004, 03:55 AM
Might there also be a difference in memory between these:

onmouseup="this.mousedown=false"
onmouseout="this.mousedown=false"
vs.
onmouseup="this.mousedown=null"
onmouseout="this.mousedown=null"

i.e., is false stored in memory, and null not...?

liorean
05-06-2004, 04:04 AM
As I guess this question is aimed at me, I'll explain it a bit. However, be sure to reread this first, since it explains the basics.

There are two components to this script, the span event handlers, and the functions themselves. Let's make a comparison:


_Global uses a global variable. That variable will stay in memory until the global scope is destroyed (that is, until the browser window is closed).

_Expando uses a local variable. That variable will only stay in memory while the function is running, and will then be garbage collected.

Thus, _Global in itself doesn't increase the memory usage compared to _Expando, but that the variable is persistent after the scope is terminated does.


However, you have the event handlers to take into account too. They also differ, in one case you store data in a global varaible, in one case you store data in an object member (also global). That is, you are cancelling the possible memory gain from using _Expando by still using a global variable.


Well, there are still something that speaks for using the _Expando instead of _Global, though: That way you can use one and the same function to handle many different draggable spans.

swmr
05-06-2004, 04:23 AM
However, you have the event handlers to take into account too. They also differ, in one case you store data in a global varaible, in one case you store data in an object member (also global). That is, you are cancelling the possible memory gain from using _Expando by still using a global variable.

Essentially what I'm wondering, now, is whether the attributes are also persistent in memory, thereby doubling the usage...

swmr
05-06-2004, 04:59 AM
Oh, the attribute was the object member... I misinterpreted that as the event handler being the object member. Nevermind me; I'm slow. :rolleyes:

swmr
05-06-2004, 09:30 AM
So, anyway, if I somehow emulate that garbage collection, (without using more than one function), wouldn't the attribute then behave like a local variable, & not increase memory-usage, overall?

For example: :D



<html>
<head>
<title>-</title>

<script type="text/JavaScript">

var mousedown;

function _Global(){
if(mousedown){
document.getElementById("output").value = "_Global: dragging";}
}

function _elState(state, el, att){

switch(state){
case "get" :
if(el.getAttributeNode(att)){
document.getElementById("output").value = "_Expando: dragging";}
break;

case "dump" :
var aNode = el.getAttributeNode(att);
if(aNode){
el.removeAttributeNode(aNode)}
document.getElementById("attLength").value = el.attributes.length;
break;

case "store" :
el.setAttributeNode(document.createAttribute(att));
document.getElementById("attLength").value = el.attributes.length;
break;}
}

</script>

</head>
<body>
<span
onmousedown="mousedown=true"
onmouseup="mousedown=false"
onmouseout="mousedown=false"
onmousemove="_Global()">
[dragMe]
</span>
<input id="output">
<span
onmousedown="_elState('store',this,'mousedown')"
onmouseup="_elState('dump',this,'mousedown')"
onmouseout="_elState('dump',this,'mousedown')"
onmousemove="_elState('get',this,'mousedown')">
[dragMe]
<label style="color:red">
<em> attributes.length: </em>
</label>
<input id="attLength">
</span>

</body>
</html>

</body>
</html>


Please let me know if I'm wrong, anyone... ;)

brothercake
05-06-2004, 09:41 AM
You have to watch out for inner functions - if you bind an expando to an element, then you have another expando inside the first, the inner function will not be garbage collected in IE. Info and solution at http://groups.google.com/groups?selm=bcslfd%24ahl%241%248300dec7%40news.demon.co.uk (that's the solution, there's more info in the wider thread)

Actually I found a memory leak in moz the other day, but I've not yet established whether it's the same thing.

swmr
05-06-2004, 11:31 AM
I don't understand: Where is my inner function, and where is my 2nd expando?

All I can see is that the attributes length either goes up or down by one.
(Also: looking at the Task Manager, both IE, and Moz will increase memory for the first few reloads, before maxing out -- even on a blank page.)

brothercake
05-06-2004, 11:59 AM
You haven't got one - it was just a general warning to look out for. Anything like this:


refToElement.onevent = function()
{
refToOtherElement.onevent = function()
{
//this function will never be garbage collected
}
}

Since the memory it uses is never released, if you have quite a few of them in a complex script you will find that IE's memory useage continually goes up as you move between pages, until it runs out or the session finishes.

I had this exact problem with my menu until someone told me about it, so I hunted for a solution and that newsgroup posting was basically it.

swmr
05-06-2004, 12:11 PM
Thanks for the heads up. :thumbsup:

swmr
05-06-2004, 01:04 PM
Now its bugging me that I can't imagine it:

When would there be a true need for an inner function, as opposed to a statement?

liorean
05-06-2004, 01:27 PM
When you want to keep a member private. When you want to create closures.

swmr
05-06-2004, 01:54 PM
ah, right; - will have to try that first hand...

As always, very kind of you for the help + repeated pointers; much appreciated. :)



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum