[Proto-Scripty] Re: Deleting a class object releasing the memory.

2010-10-26 Thread RobG


On Oct 25, 9:40 pm, Paco Gómez  wrote:
> Hi TJ,
>
> I'm Jose's partner. The thing I don't understand is why we can recover
> memory after creating any other kind of object, but not with DOM
> elements.

I don't see the issue in either Firefox or IE 6.

[...]
> Do you have any idea why is this happening? I believe that if we at
> least can free this nodes in this simple example we could understand
> why they are not being freed in our big application.
> I'm guessing that it could be related to:
> - Something in the initialize of element class (we add the element to
> some cache)
> - Something in the insert method
> - References that are being stored in each element (to its parent and
> child nodes) make it impossible for IE to remove them from memory.

Easy to test: use plain DOM instead and see if you get the same
result.

Here's an example:

function doTest(n) {
  var elementArray = [];
  while (n--) {
elementArray[n] = document.createElement('div').
  appendChild(document.createTextNode('test
text'));
  }
  alert('Before destroy');
  elementArray.length = 0;
  alert('After destroy');
}
doTest(3000);


Incidentally, the above uses very little memory and is 10 to 40 times
faster, so you can see that Class.create() is a very inefficient
factory.


--
Rob

-- 
You received this message because you are subscribed to the Google Groups 
"Prototype & script.aculo.us" group.
To post to this group, send email to prototype-scriptacul...@googlegroups.com.
To unsubscribe from this group, send email to 
prototype-scriptaculous+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/prototype-scriptaculous?hl=en.



[Proto-Scripty] Re: Deleting a class object releasing the memory.

2010-10-25 Thread T.J. Crowder
Hi,

> Do you have any idea why is this happening?

Well, assuming it _is_ actually happening as opposed to being a
measurement error, I'm afraid not. The thing (again) that I'm not sure
Jose was really clear on was that memory will NOT be freed immediately
just because you stopped referencing it, there's a lag. It looks like
sEIVe helps you know what nodes are still referenced, which is handy,
but I don't know whether it introduces issues (never having used it).

> I'm guessing that it could be related to:
> - Something in the initialize of element class (we add the element to
> some cache)
> - Something in the insert method
> - References that are being stored in each element (to its parent and
> child nodes) make it impossible for IE to remove them from memory.

Well, it seems like it should be trivial to test each of those. For
instance, you can test with and without `insert`:

// #1. Original
var element = new Element("div").insert("test code");

// #2. Without insert
var element = new Element("div");
element.appendChild(document.createTextNode("test code"));

Similarly, getting all of the Prototype stuff out of the way:

// 3. Without `new Element` or `insert`
var element = document.createElement("div");
element.appendChild(document.createTextNode("test code"));

I did a quick test, all I really have time for, and was interested to
see that IE6 takes _dramatically_ longer to do #1 than it does #2
above. Doing #2 above memory use seemed relatively stable.

FWIW,

-- T.J.

On Oct 25, 12:40 pm, Paco Gómez  wrote:
> Hi TJ,
>
> I'm Jose's partner. The thing I don't understand is why we can recover
> memory after creating any other kind of object, but not with DOM
> elements. For example, this memory is recovered after destroying the
> object: (http://pastie.org/1247004)
> var TestClass = Class.create({
>     initialize: function() {
>         this.options = {
>                         bigString: new Array(1000).join(new 
> Array(3000).join("X"))
>         };
>     },
>     destroy: function() {
>         alert('before destroy');
>         this.options = null;
>         alert('after destroy');
>     }
>
> });
>
> function execute2(){
>     var myObject = new TestClass();
>     myObject.destroy();
>
> }
>
> But the same code, trying to destroy Element objects is not working in
> some cases.
>
> Example 1: memory is recovered when using new Element and not
> inserting anything inside: (http://www.pastie.org/1247025)
> var TestClass = Class.create({
>     initialize: function() {
>         this.options = {
>                         array: $A()
>         };
>
>                 for(var i=0; i<3000; i++){
>                         var element = new Element("div");
>                         this.options.array.push(element);
>                 }
>
>     },
>     destroy: function() {
>         alert('before destroy');
>                 for(var i=0; i                         this.options.array[i]=null;
>                 }
>                 delete this.options.array;
>         delete this.options;
>         alert('after destroy');
>     }
>
> });
>
> By the way, it doesn't matter if we nullify every element in the array
> or not, as you said before. That's a good thing to know :-)
> In this example we recover only half of the memory, but that's not a
> problem. If we execute this same code some more times this "extra"
> memory doesn't increase.
> We test these things using sIEve (http://home.orange.nl/jsrosman/). We
> can see there that the number of DOM nodes that are being used is back
> to normal after destroying the object.
>
> Example 2 (http://www.pastie.org/1247055):memory is NOT recovered:
> var TestClass = Class.create({
>     initialize: function() {
>         this.options = {
>                         array: $A()
>         };
>
>                 for(var i=0; i<3000; i++){
>                         var element = new Element("div").insert("test code");
>                         this.options.array.push(element);
>                 }
>
>     },
>     destroy: function() {
>         alert('before destroy');
>                 for(var i=0; i                         this.options.array[i]=null;
>                 }
>                 delete this.options.array;
>         delete this.options;
>         alert('after destroy');
>     }
>
> });
>
> function execute2(){
>     var myObject = new TestClass();
>     myObject.destroy();
>
> }
>
> Here the only difference is that the nodes we insert have text inside:
> var element = new Element("div").insert("test code");
> Now we can see that memory is not freed, and that the number of nodes
> used after being destroyed is 6000. (they are not being freed, like if
> something was referencing them).
>
> Do you have any idea why is this happening? I believe that if we at
> least can free this nodes in this simple example we could understand
> why they are not being freed in our big application.
> I'm guessing that it could be related to:
> - Som

[Proto-Scripty] Re: Deleting a class object releasing the memory.

2010-10-25 Thread Paco Gómez
Hi TJ,

I'm Jose's partner. The thing I don't understand is why we can recover
memory after creating any other kind of object, but not with DOM
elements. For example, this memory is recovered after destroying the
object: (http://pastie.org/1247004)
var TestClass = Class.create({
initialize: function() {
this.options = {
bigString: new Array(1000).join(new 
Array(3000).join("X"))
};
},
destroy: function() {
alert('before destroy');
this.options = null;
alert('after destroy');
}
});

function execute2(){
var myObject = new TestClass();
myObject.destroy();
}

But the same code, trying to destroy Element objects is not working in
some cases.

Example 1: memory is recovered when using new Element and not
inserting anything inside: (http://www.pastie.org/1247025)
var TestClass = Class.create({
initialize: function() {
this.options = {
array: $A()
};

for(var i=0; i<3000; i++){
var element = new Element("div");
this.options.array.push(element);
}

},
destroy: function() {
alert('before destroy');
for(var i=0; ihttp://home.orange.nl/jsrosman/). We
can see there that the number of DOM nodes that are being used is back
to normal after destroying the object.

Example 2 (http://www.pastie.org/1247055): memory is NOT recovered:
var TestClass = Class.create({
initialize: function() {
this.options = {
array: $A()
};

for(var i=0; i<3000; i++){
var element = new Element("div").insert("test code");
this.options.array.push(element);
}


},
destroy: function() {
alert('before destroy');
for(var i=0; ihttp://groups.google.com/group/prototype-scriptaculous?hl=en.



[Proto-Scripty] Re: Deleting a class object releasing the memory.

2010-10-25 Thread T.J. Crowder
Hi,

> So, why is deleting this variable and not the array? it sounds very
> strange for me.

Again, in my tests using a real browser and looking at the memory used
by the browser as reported by the operating system, the memory used by
the elements in the array _is_ getting released, over time, and
reasonably proactively -- by all of the browsers I tried.

-- T.J.

On Oct 25, 10:40 am, jose maria Cano  wrote:
> Hi again,
> Thanks a lot for your time and help.
> But still something that I can't understand.
>
> The property object options has 3 variables inside:
>
>  this.options = {
>             vari: '',
>             array: '',
>             testDiv: ''
>         };
>
> What I can't understand is that for "vari" and "testDiv" is releasing
> the memory.
>
> You can use this programhttp://home.orange.nl/jsrosman/to see the
> memory and the DOM elements used and you'll see how after the destroy
> 1 node is released, the node for the "testDiv" variable.
>
> So, why is deleting this variable and not the array? it sounds very
> strange for me.
>
> Thanks a lot for your help!!
>
> Kr, Jose
>
> On 22 oct, 18:20, "T.J. Crowder"  wrote:
>
>
>
>
>
>
>
> > Hi,
>
> > Sorry, all of the numbers in my original post are off by 1,000. I was
> > writing "32k" when I should have been writing "32,000k" (or ~31M).
> > Sorry about that, misread the Chrome memory page and failed to
> > think. :-)
>
> > > But the problem is still there, I don’t know how to release the memory
> > > used by this.options, using your code, the variable is using almost
> > > 450 MB in explorer and this memory is never released.
>
> > There's something different in your setup, then. When I ran that test
> > page on my Windows 7 box, IE8 released the memory *much* more
> > aggressively than that, it never once went above about 57M. You're
> > really seeing 450MB of memory consumed using the test pages I posted?
>
> > Later: I've had IE8 open and runninghttp://pastie.org/1240613for
> > about 25 minutes. It's done 4,180 loops, and so created and released
> > ~8,364,180 divs (4,180 x 2,001). It's cycling between about 30M and
> > 50M, which is what it's been doing since I started it. It's very
> > nearly steady-state, as close to it as I would expect since I'm using
> > a version of the code that's keeping the TestObject instances (which
> > won't account for more than a few hundred k). No evidence of a memory
> > leak at all.
>
> > > So, do you have any idea on how to release the memory?
>
> > Just what I said above: *You* can't release the memory, you can only
> > release your references to it (which you are). It's up to IE to
> > actually reclaim it, _if_ and _when_ it thinks it should. JavaScript
> > is a garbage-collected[1] environment.
>
> > > I really need
> > > to know how to delete a global variable like this.options
>
> > It's not a global variable, it's a property on an object. You delete
> > it exactly as you originally tried to:
>
> >     delete this.options;
>
> > At that point, it's down to the JavaScript implementation (IE's
> > JScript, in this case) to actually release the memory.
>
> > In terms of actually dealing with the problem you're seeing, I hate to
> > say it, but it sounds like you're probably not going to get a quick
> > fix. :-( You'll have to audit the code, ensure there are no circular
> > references anywhere (which _will_ cause memory leaks), make sure you
> > don't have references being kept active by closures (you don't in your
> > example code, but as we've said, that was just test code), etc.
>
> > [1]http://en.wikipedia.org/wiki/Garbage_collection_(computer_science)
>
> > Good luck,
> > --
> > T.J. Crowder
> > Independent Software Engineer
> > tj / crowder software / com
> > www / crowder software / com
>
> > On Oct 22, 3:02 pm, jose maria Cano  wrote:
>
> > > Hi,
> > > First of all, thanks a lot for your time and help.
>
> > > I forgot to say that the problem is using windows and IE8 (of course…)
> > > but I have to support IE for some clients.
> > > Also, the class is a test class, is not doing anything “useful”, is
> > > just to see how to release the memory in IE, the real application is a
> > > huge application with thousands of nodes, variables, events… and after
> > > 30 minutes working on IE you have like 500 MB used.
>
> > > I’ve been making some tests with your code and indeed the memory used
> > > is the same doing null to the whole array or just doing delete
> > > this.options
>
> > > But the problem is still there, I don’t know how to release the memory
> > > used by this.options, using your code, the variable is using almost
> > > 450 MB in explorer and this memory is never released.
>
> > > I don’t know how to attach a screenshot here to show you the memory….
>
> > > So, do you have any idea on how to release the memory? I really need
> > > to know how to delete a global variable like this.options and for the
> > > moment I don’t see how to it…..
>
> > > Thanks a lot for your time
>
> > > kr, Jose
> > >

[Proto-Scripty] Re: Deleting a class object releasing the memory.

2010-10-25 Thread jose maria Cano
Hi again,
Thanks a lot for your time and help.
But still something that I can't understand.

The property object options has 3 variables inside:

 this.options = {
vari: '',
array: '',
testDiv: ''
};

What I can't understand is that for "vari" and "testDiv" is releasing
the memory.

You can use this program http://home.orange.nl/jsrosman/ to see the
memory and the DOM elements used and you'll see how after the destroy
1 node is released, the node for the "testDiv" variable.

So, why is deleting this variable and not the array? it sounds very
strange for me.

Thanks a lot for your help!!

Kr, Jose

On 22 oct, 18:20, "T.J. Crowder"  wrote:
> Hi,
>
> Sorry, all of the numbers in my original post are off by 1,000. I was
> writing "32k" when I should have been writing "32,000k" (or ~31M).
> Sorry about that, misread the Chrome memory page and failed to
> think. :-)
>
> > But the problem is still there, I don’t know how to release the memory
> > used by this.options, using your code, the variable is using almost
> > 450 MB in explorer and this memory is never released.
>
> There's something different in your setup, then. When I ran that test
> page on my Windows 7 box, IE8 released the memory *much* more
> aggressively than that, it never once went above about 57M. You're
> really seeing 450MB of memory consumed using the test pages I posted?
>
> Later: I've had IE8 open and runninghttp://pastie.org/1240613for
> about 25 minutes. It's done 4,180 loops, and so created and released
> ~8,364,180 divs (4,180 x 2,001). It's cycling between about 30M and
> 50M, which is what it's been doing since I started it. It's very
> nearly steady-state, as close to it as I would expect since I'm using
> a version of the code that's keeping the TestObject instances (which
> won't account for more than a few hundred k). No evidence of a memory
> leak at all.
>
> > So, do you have any idea on how to release the memory?
>
> Just what I said above: *You* can't release the memory, you can only
> release your references to it (which you are). It's up to IE to
> actually reclaim it, _if_ and _when_ it thinks it should. JavaScript
> is a garbage-collected[1] environment.
>
> > I really need
> > to know how to delete a global variable like this.options
>
> It's not a global variable, it's a property on an object. You delete
> it exactly as you originally tried to:
>
>     delete this.options;
>
> At that point, it's down to the JavaScript implementation (IE's
> JScript, in this case) to actually release the memory.
>
> In terms of actually dealing with the problem you're seeing, I hate to
> say it, but it sounds like you're probably not going to get a quick
> fix. :-( You'll have to audit the code, ensure there are no circular
> references anywhere (which _will_ cause memory leaks), make sure you
> don't have references being kept active by closures (you don't in your
> example code, but as we've said, that was just test code), etc.
>
> [1]http://en.wikipedia.org/wiki/Garbage_collection_(computer_science)
>
> Good luck,
> --
> T.J. Crowder
> Independent Software Engineer
> tj / crowder software / com
> www / crowder software / com
>
> On Oct 22, 3:02 pm, jose maria Cano  wrote:
>
>
>
>
>
>
>
> > Hi,
> > First of all, thanks a lot for your time and help.
>
> > I forgot to say that the problem is using windows and IE8 (of course…)
> > but I have to support IE for some clients.
> > Also, the class is a test class, is not doing anything “useful”, is
> > just to see how to release the memory in IE, the real application is a
> > huge application with thousands of nodes, variables, events… and after
> > 30 minutes working on IE you have like 500 MB used.
>
> > I’ve been making some tests with your code and indeed the memory used
> > is the same doing null to the whole array or just doing delete
> > this.options
>
> > But the problem is still there, I don’t know how to release the memory
> > used by this.options, using your code, the variable is using almost
> > 450 MB in explorer and this memory is never released.
>
> > I don’t know how to attach a screenshot here to show you the memory….
>
> > So, do you have any idea on how to release the memory? I really need
> > to know how to delete a global variable like this.options and for the
> > moment I don’t see how to it…..
>
> > Thanks a lot for your time
>
> > kr, Jose
> > On 22 oct, 14:59, "T.J. Crowder"  wrote:
>
> > > Hi,
>
> > > > I have a big problem in my application, when I create a global class
> > > > object is impossible for me to release the memory and I'm having
> > > > memory leaks.
>
> > > It looks to me like you're doing nearly everything you need to do (and
> > > a little bit more). Remember that all you can do is make sure that
> > > memory is no longer referenced (which it looks to me like you've done
> > > almost completely) and that you've broken any _circular_ references
> > > between DOM elements and JavaScript objects (you don't ha

[Proto-Scripty] Re: Deleting a class object releasing the memory.

2010-10-22 Thread T.J. Crowder
Hi,

Sorry, all of the numbers in my original post are off by 1,000. I was
writing "32k" when I should have been writing "32,000k" (or ~31M).
Sorry about that, misread the Chrome memory page and failed to
think. :-)

> But the problem is still there, I don’t know how to release the memory
> used by this.options, using your code, the variable is using almost
> 450 MB in explorer and this memory is never released.

There's something different in your setup, then. When I ran that test
page on my Windows 7 box, IE8 released the memory *much* more
aggressively than that, it never once went above about 57M. You're
really seeing 450MB of memory consumed using the test pages I posted?

Later: I've had IE8 open and running http://pastie.org/1240613 for
about 25 minutes. It's done 4,180 loops, and so created and released
~8,364,180 divs (4,180 x 2,001). It's cycling between about 30M and
50M, which is what it's been doing since I started it. It's very
nearly steady-state, as close to it as I would expect since I'm using
a version of the code that's keeping the TestObject instances (which
won't account for more than a few hundred k). No evidence of a memory
leak at all.

> So, do you have any idea on how to release the memory?

Just what I said above: *You* can't release the memory, you can only
release your references to it (which you are). It's up to IE to
actually reclaim it, _if_ and _when_ it thinks it should. JavaScript
is a garbage-collected[1] environment.

> I really need
> to know how to delete a global variable like this.options

It's not a global variable, it's a property on an object. You delete
it exactly as you originally tried to:

delete this.options;

At that point, it's down to the JavaScript implementation (IE's
JScript, in this case) to actually release the memory.

In terms of actually dealing with the problem you're seeing, I hate to
say it, but it sounds like you're probably not going to get a quick
fix. :-( You'll have to audit the code, ensure there are no circular
references anywhere (which _will_ cause memory leaks), make sure you
don't have references being kept active by closures (you don't in your
example code, but as we've said, that was just test code), etc.

[1] http://en.wikipedia.org/wiki/Garbage_collection_(computer_science)

Good luck,
--
T.J. Crowder
Independent Software Engineer
tj / crowder software / com
www / crowder software / com

On Oct 22, 3:02 pm, jose maria Cano  wrote:
> Hi,
> First of all, thanks a lot for your time and help.
>
> I forgot to say that the problem is using windows and IE8 (of course…)
> but I have to support IE for some clients.
> Also, the class is a test class, is not doing anything “useful”, is
> just to see how to release the memory in IE, the real application is a
> huge application with thousands of nodes, variables, events… and after
> 30 minutes working on IE you have like 500 MB used.
>
> I’ve been making some tests with your code and indeed the memory used
> is the same doing null to the whole array or just doing delete
> this.options
>
> But the problem is still there, I don’t know how to release the memory
> used by this.options, using your code, the variable is using almost
> 450 MB in explorer and this memory is never released.
>
> I don’t know how to attach a screenshot here to show you the memory….
>
> So, do you have any idea on how to release the memory? I really need
> to know how to delete a global variable like this.options and for the
> moment I don’t see how to it…..
>
> Thanks a lot for your time
>
> kr, Jose
> On 22 oct, 14:59, "T.J. Crowder"  wrote:
>
>
>
>
>
>
>
> > Hi,
>
> > > I have a big problem in my application, when I create a global class
> > > object is impossible for me to release the memory and I'm having
> > > memory leaks.
>
> > It looks to me like you're doing nearly everything you need to do (and
> > a little bit more). Remember that all you can do is make sure that
> > memory is no longer referenced (which it looks to me like you've done
> > almost completely) and that you've broken any _circular_ references
> > between DOM elements and JavaScript objects (you don't have any
> > circular references, but you've broken all refs from JavaScript->DOM,
> > which is a good thing to do). At that point, it's up to the JavaScript
> > implementation when (and whether) to actually reclaim the memory. Some
> > are more aggressive than others, and some are more effective than
> > others.
>
> > Your actual quoted code ends up being very nearly a no-op, which I'm
> > guessing is for testing purposes. It creates 2,000 divs and pushes
> > them on an array (and another div it puts in a property) but never
> > adds them to the document. It then removes the references to them from
> > the array and releases the array (and clears the property). Assuming
> > this code:
>
> >     var t = new TestClass();
>
> > ...by the time the line above is complete, the only remaining memory
> > references I see are the instance itself (`t` ab

[Proto-Scripty] Re: Deleting a class object releasing the memory.

2010-10-22 Thread jose maria Cano
Hi,
First of all, thanks a lot for your time and help.

I forgot to say that the problem is using windows and IE8 (of course…)
but I have to support IE for some clients.
Also, the class is a test class, is not doing anything “useful”, is
just to see how to release the memory in IE, the real application is a
huge application with thousands of nodes, variables, events… and after
30 minutes working on IE you have like 500 MB used.

I’ve been making some tests with your code and indeed the memory used
is the same doing null to the whole array or just doing delete
this.options

But the problem is still there, I don’t know how to release the memory
used by this.options, using your code, the variable is using almost
450 MB in explorer and this memory is never released.

I don’t know how to attach a screenshot here to show you the memory….

So, do you have any idea on how to release the memory? I really need
to know how to delete a global variable like this.options and for the
moment I don’t see how to it…..

Thanks a lot for your time

kr, Jose
On 22 oct, 14:59, "T.J. Crowder"  wrote:
> Hi,
>
> > I have a big problem in my application, when I create a global class
> > object is impossible for me to release the memory and I'm having
> > memory leaks.
>
> It looks to me like you're doing nearly everything you need to do (and
> a little bit more). Remember that all you can do is make sure that
> memory is no longer referenced (which it looks to me like you've done
> almost completely) and that you've broken any _circular_ references
> between DOM elements and JavaScript objects (you don't have any
> circular references, but you've broken all refs from JavaScript->DOM,
> which is a good thing to do). At that point, it's up to the JavaScript
> implementation when (and whether) to actually reclaim the memory. Some
> are more aggressive than others, and some are more effective than
> others.
>
> Your actual quoted code ends up being very nearly a no-op, which I'm
> guessing is for testing purposes. It creates 2,000 divs and pushes
> them on an array (and another div it puts in a property) but never
> adds them to the document. It then removes the references to them from
> the array and releases the array (and clears the property). Assuming
> this code:
>
>     var t = new TestClass();
>
> ...by the time the line above is complete, the only remaining memory
> references I see are the instance itself (`t` above) and the fact that
> `t` has a property called `options` (which has the value null). If you
> uncomment the `delete this.options;` line, then even the `options`
> property that will be gone.
>
> I took your code and put it (sans alerts) in a page that created 20
> TestClass objects every 250ms and then threw them away. Using Chrome's
> excellent about:memory page, I was able to see that the memory does
> (eventually) get reclaimed by Chrome, Firefox, and Opera on Linux, IE6
> on Windows 2000, and IE8 on Windows 7. They were wildly different
> about when they did it. Chrome started at using 12k for the page,
> which shot up to 60k almost immediately (certainly on the first 40-60
> TestClass instances), and then allowed memory use to go up to 85-95k
> before reclaiming back down to 62-64k and letting it climb again.
> Firefox 3.6 started at about 50k and allowed use to creep up to 250k
> before reclaiming back down to ~70k again (rinse, repeat). Opera was
> the most aggressive about reclaiming the memory, starting at 38k,
> jumping almost immediately to 57k and then staying there, almost
> completely steady. On Windows, IE8 started at about 33k and allowed
> that to grow to about 57-59k before reclaiming back down to 33k again
> and allowing it to grow. (Wow is IE slow.) Even IE6 on Windows 2000
> (measured via Task Manager rather than Chrome) reclaimed the memory
> (occillating between 7k and 25k).
>
> Then I modified the code to retain the TestClass instances, to test
> whether the instances were somehow keeping the elements in memory. In
> all five cases (Chrome, Firefox, and Opera under Linux, IE8 under
> Windows, and IE6 under Windows), they weren't. The memory use was
> virtually identical to the first test, which shows that by the time
> you've done your "destroy", the instances *don't* retain any memory
> references that prevent cleanup. (The instances themselves will be
> very small.)
>
> BTW, you don't need to explicitly null-out the array elements before
> releasing the array. I've heard people say you do, but it doesn't make
> any sense from a JavaScript specification perspective (not that that
> matters, particularly not when you're talking about IE) but this
> seemed like a good opportunity to test it for myself. Commenting out
> the loop in `destroy` that nulls out the elements made no difference,
> not even on IE6. I think it's a myth.
>
> So that means your `destroy` can consist entirely of this:
>
>     destroy: function() {
>         delete this.options;
>     }
>
> ...since you're keeping everythi

[Proto-Scripty] Re: Deleting a class object releasing the memory.

2010-10-22 Thread T.J. Crowder
Hi,

> I have a big problem in my application, when I create a global class
> object is impossible for me to release the memory and I'm having
> memory leaks.

It looks to me like you're doing nearly everything you need to do (and
a little bit more). Remember that all you can do is make sure that
memory is no longer referenced (which it looks to me like you've done
almost completely) and that you've broken any _circular_ references
between DOM elements and JavaScript objects (you don't have any
circular references, but you've broken all refs from JavaScript->DOM,
which is a good thing to do). At that point, it's up to the JavaScript
implementation when (and whether) to actually reclaim the memory. Some
are more aggressive than others, and some are more effective than
others.

Your actual quoted code ends up being very nearly a no-op, which I'm
guessing is for testing purposes. It creates 2,000 divs and pushes
them on an array (and another div it puts in a property) but never
adds them to the document. It then removes the references to them from
the array and releases the array (and clears the property). Assuming
this code:

var t = new TestClass();

...by the time the line above is complete, the only remaining memory
references I see are the instance itself (`t` above) and the fact that
`t` has a property called `options` (which has the value null). If you
uncomment the `delete this.options;` line, then even the `options`
property that will be gone.

I took your code and put it (sans alerts) in a page that created 20
TestClass objects every 250ms and then threw them away. Using Chrome's
excellent about:memory page, I was able to see that the memory does
(eventually) get reclaimed by Chrome, Firefox, and Opera on Linux, IE6
on Windows 2000, and IE8 on Windows 7. They were wildly different
about when they did it. Chrome started at using 12k for the page,
which shot up to 60k almost immediately (certainly on the first 40-60
TestClass instances), and then allowed memory use to go up to 85-95k
before reclaiming back down to 62-64k and letting it climb again.
Firefox 3.6 started at about 50k and allowed use to creep up to 250k
before reclaiming back down to ~70k again (rinse, repeat). Opera was
the most aggressive about reclaiming the memory, starting at 38k,
jumping almost immediately to 57k and then staying there, almost
completely steady. On Windows, IE8 started at about 33k and allowed
that to grow to about 57-59k before reclaiming back down to 33k again
and allowing it to grow. (Wow is IE slow.) Even IE6 on Windows 2000
(measured via Task Manager rather than Chrome) reclaimed the memory
(occillating between 7k and 25k).

Then I modified the code to retain the TestClass instances, to test
whether the instances were somehow keeping the elements in memory. In
all five cases (Chrome, Firefox, and Opera under Linux, IE8 under
Windows, and IE6 under Windows), they weren't. The memory use was
virtually identical to the first test, which shows that by the time
you've done your "destroy", the instances *don't* retain any memory
references that prevent cleanup. (The instances themselves will be
very small.)

BTW, you don't need to explicitly null-out the array elements before
releasing the array. I've heard people say you do, but it doesn't make
any sense from a JavaScript specification perspective (not that that
matters, particularly not when you're talking about IE) but this
seemed like a good opportunity to test it for myself. Commenting out
the loop in `destroy` that nulls out the elements made no difference,
not even on IE6. I think it's a myth.

So that means your `destroy` can consist entirely of this:

destroy: function() {
delete this.options;
}

...since you're keeping everything on the `options` object.

Here are the test files:
http://pastie.org/1240577 - the basic counter test
http://pastie.org/1240579 - keep the instances test
http://pastie.org/1240582 - don't null out array entries test
http://pastie.org/1240613 - using the one-liner `destroy` above

HTH,
--
T.J. Crowder
Independent Software Engineer
tj / crowder software / com
www / crowder software / com

On Oct 22, 10:52 am, jose maria Cano  wrote:
> Hi guys,
> I have a big problem in my application, when I create a global class
> object is impossible for me to release the memory and I'm having
> memory leaks.
>
> I've made a small class as example.
>
> var TestClass = Class.create({
>
>     initialize: function() {
>         this.options = {
>             vari: '',
>             array: '',
>             testDiv: ''
>         };
>         this.addElement();
>     },
>     addElement: function(element) {
>         var a = 0;
>         var arrayDivs = [];
>         alert('before create element');
>         for (var i = 0; i < 2000; i++) {
>             var div = new Element('div');
>             div.innerHTML = 'test' + i;
>             arrayDivs.push(div);
>         }
>         alert('after create element');
>         this.options