XMLHttpRequest & garbage collector

D

daniel.internet

Hello,

I got one question, that may seems trivial to you, but I really dont
understand it. Let's say we got this code:

function ajax()
{
var obj;
obj = new ActiveXObject("Microsoft.XMLHTTP");
obj.onreadystatechange = function ()
{
[anycode];
};
obj.open("GET", "http://www.park.sk", true);
obj.send(null);
}


(for simplicity i created XHR just for IE as activex). As far as I
know, browsers's garbage collector should discard all function's local
variables after functions exits, if none of inner objects (variables)
got reference out of that function. But as we all know, XHR object
persists in memory and becuase it refers to locally created function
(onreadystatechange), all local varibales stay in memory as well
(because of closures). But why does garbace collector not discard
activex object after function ajax exits? It does not have any
reference out of that function's scope.

It looks like that browser creates some hidden reference to that
activex object AFTER i call "send" method (so browser wont discard
it), and delete that reference after XHR objects's state change to
LOADED.

Please make it clear to me. I really cant find the answer.
 
V

VK

It looks like that browser creates some hidden reference to that
activex object AFTER i call "send" method (so browser wont discard
it),

No, an outside reference is created at the moment of executing
new ActiveXObject(...
In case of IE a reverence is placed to the query pool provided by
HTTP.sys This reference also ensures that the entire closure - so the
whole function ajax() with all its current arguments and internal vars
- gets "frozen" so excluded from the garbage collection.

As a side note: the default garbage collection frequency for HTTP.sys
pool is 3 minutes, JScript garbage collector frequency is 1 minute -
unless one has changes default registry settings. That means that with
a low load it may take up to 4 minutes before memory release. It is
not a problem for an automated memory management, because with higher
load GC passes gets more frequent right a way. Just a note for a C++
programmer if she looks at SysMonitor after each operation - a totally
useless doing most of the time in Java/JavaScript :)
and delete that reference after XHR objects's state change to
LOADED.

It may or may not - depends on what is there in your closure, that is
especially true for outside objects - and ActiveX are alien objects to
JScript engine. In many serious libraries the clearance is made
manually, see for instance AJAXToolBox:
http://www.ajaxtoolbox.com/request/source.php

See also:

http://blogs.msdn.com/ericlippert/archive/2003/09/17/53038.aspx
"How Do The Script Garbage Collectors Work?"

http://msdn.microsoft.com/msdnmag/issues/02/04/web/
"Why doesn't the garbage collector release a reference to an ActiveX®
object when the page is refreshed?"
 
V

VK

As a side note: the default garbage collection frequency for HTTP.sys
pool is 3 minutes

Corection: 120 sec, so 2 min

So with the default UriScavengerPeriod and GcValTrigger registry value
up to 180 sec (3min) before the memory is actually released. Again:
with the low load / big free memory.
 
R

Richard Cornford

I got one question, that may seems trivial to you, but
I really dont understand it. Let's say we got this code:

function ajax()
{
var obj;
obj = new ActiveXObject("Microsoft.XMLHTTP");
obj.onreadystatechange = function ()
{
[anycode];
};
obj.open("GET", "http://www.park.sk", true);
obj.send(null);
}


(for simplicity i created XHR just for IE as activex). As
far as I know, browsers's garbage collector should discard
all function's local variables after functions exits,

Not if a closure is formed. If a closure is created the containing
function's local variables cannot be discarded until the closure is
removed.
if none of inner objects (variables)
got reference out of that function.
But as we all know, XHR object persists in memory and
becuase it refers to locally created function
(onreadystatechange), all local varibales stay in memory as well
(because of closures). But why does garbace collector not discard
activex object after function ajax exits?

That is IE's circular reference memory leak problem. You have created a
circular chain of references that includes a COM object (the XML HTTP
request object) and javascript objects (the inner function object and
the Activation/Variable object of the outer function). IE (at least <=
6) cannot break that circle and cannot see when it is isolated from the
rest of the system, so it cannot garbage collect any of the objects
involved.
It does not have any
reference out of that function's scope.

That doesn't matter here.
It looks like that browser creates some hidden reference to
that activex object AFTER i call "send" method (so browser
wont discard it), and delete that reference after XHR
objects's state change to LOADED.

No, if you break the circle then IE will garbage collect the objects
when they are finished with.
Please make it clear to me. I really cant find the answer.

Google for "IE Memory leak" and you will find answers (and 50% or so of
them will not be paranoid over-reactions).

Richard.
 
A

Alexey Kulentsov

Richard said:
That is IE's circular reference memory leak problem. You have created a
circular chain of references that includes a COM object (the XML HTTP
request object) and javascript objects (the inner function object and
the Activation/Variable object of the outer function). IE (at least <=
6) cannot break that circle and cannot see when it is isolated from the
rest of the system, so it cannot garbage collect any of the objects
involved.
I test it on IE7, the same problem!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,157
Latest member
MercedesE4
Top