473,320 Members | 2,083 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

Aync XMLHTTP with Javascript: memory problems

Currently I'm doing some experimenting with the XMLHTTP object in
Javascript. Now,
the XMLHttp object is asynchronous (at least in this case), and the
following code causes a significant memory loss even though I seem to be
allocaitng everything; help would be *vastly* appreciated. What am I doing
wrong here? I thought I was doing everything correctly (setting things to
null, for example) but none of the memory seems to get replaced. I've been
experiencing allocations of memory up to 125 megabytes (!) that simply
persist in the browser, never to go away...

Thanks in advance for any help you can provide!

ASyncQueue = new Array();
-Justice
function DataHandlerLookupLoop(value, id, numberOfLoops)

{

for (var loopCount = 0; loopCount < numberOfLoops; loopCount++)

{

DataHandlerLookup(loopCount,loopCount,id);

}

}

function DataHandlerLookup(value, number, id)

{

++asyncsRunning;

AsyncQueue.push(new Object());

AsyncQueue[number].ThisElement = document.getElementById(id);

AsyncQueue[number].Server = new ActiveXObject("Msxml2.XMLHTTP");

AsyncQueue[number].Server.onreadystatechange = f;

AsyncQueue[number].Server.open("GET",
"http://localhost/MyCompany/data.metadata?text=" + value, true);

AsyncQueue[number].Server.send(value);

}

function f()

{

var temporaryLength = AsyncQueue.length;

for (var index = 0; index < AsyncQueue.length; ++index)

{

if (AsyncQueue[index] != null)

{

if (AsyncQueue[index].Server.readyState == FINISHED)

{

AsyncQueue[index].Server.abort();

AsyncQueue[index].Server = null;

delete AsyncQueue[index].Server;

AsyncQueue[index].ThisElement = null;

delete AsyncQueue[index].ThisElement;

AsyncQueue[index] = null;

--asyncsRunning;

}

if (asyncsRunning == 0)

{

var tempQueueLength = AsyncQueue.length;

for (var ix = 0; ix < tempQueueLength; ++ix)

{

AsyncQueue.pop();

}

CollectGarbage();

}

}

Jul 20 '05 #1
5 6044
On Fri, 28 Nov 2003 03:47:14 GMT, "Justice" <ju**********@hotmail.com>
wrote:
Currently I'm doing some experimenting with the XMLHTTP object in
Javascript. Now,
the XMLHttp object is asynchronous (at least in this case), and the
following code causes a significant memory loss even though I seem to be
allocaitng everything; help would be *vastly* appreciated. What am I doing
wrong here? I thought I was doing everything correctly (setting things to
null, for example) but none of the memory seems to get replaced. I've been
experiencing allocations of memory up to 125 megabytes (!) that simply
persist in the browser, never to go away...
<snip />

Been there, done that.
AsyncQueue[index].Server.abort();

AsyncQueue[index].Server = null;

delete AsyncQueue[index].Server;

AsyncQueue[index].ThisElement = null;

delete AsyncQueue[index].ThisElement;

AsyncQueue[index] = null; You don't need to call abort() or any of the 4 lines after that.
CollectGarbage();

CollectGarbage won't solve your problems. It is only useful in
debugging as it forces the garbage collector to run at a known point.

Aside from executing code too many times (the f() function is called 3
times per HTTP request and you loop through each item in your array),
there doesn't appear to be any problems noticable at first glance.
But this isn't your actual code, is it? It doesn't make much sense to
make HTTP requests but do nothing with the results....

Regards,
Steve
Jul 20 '05 #2

"Steve van Dongen" <st*****@hotmail.com> wrote in message
news:uk********************************@4ax.com...
Been there, done that.
AsyncQueue[index].Server.abort();

AsyncQueue[index].Server = null;

delete AsyncQueue[index].Server;

AsyncQueue[index].ThisElement = null;

delete AsyncQueue[index].ThisElement;

AsyncQueue[index] = null; You don't need to call abort() or any of the 4 lines after that.

CollectGarbage();

CollectGarbage won't solve your problems. It is only useful in
debugging as it forces the garbage collector to run at a known point.


I simply threw it in to see if memory was actually being deallocated.
Unfortunately, nothing really changed.
Aside from executing code too many times (the f() function is called 3
times per HTTP request and you loop through each item in your array),
How can I necessarily avoid calling f three times, however? Attaching f to
onreadystatechange basically guarantees that this thing is going to get
called every time.

Ideally, I would have liked a way in "f" to determine which server object
fired the onreadystatechange event, but no information comes back from
onreadystatechange to indicate this, hence my convoluted attempts at
resolving things.
there doesn't appear to be any problems noticable at first glance.
But this isn't your actual code, is it? It doesn't make much sense to
make HTTP requests but do nothing with the results....


You're correct. However, even this code (without anything notable in
function "f", which would do something w/ the results) leads to memory
leaks. If I simulate an environment where, say, 400 of these requests are
made, the memory piles up and piles up and eventually I have IE using 156
megabytes of memory.

Unfortunately, although there don't *seem* to be any problems noticeable
(that's what I thought too, other than some semi-inefficient ways of going
through the asynclist) the memory allocations for this are enormous when 200
or so requests go through.

Thanks for any insight you can provide,
-Justice
Jul 20 '05 #3
On Sun, 30 Nov 2003 05:09:09 GMT, "Justice" <ju**********@hotmail.com>
wrote:

"Steve van Dongen" <st*****@hotmail.com> wrote in message
news:uk********************************@4ax.com.. .
Been there, done that.
> AsyncQueue[index].Server.abort();
>
> AsyncQueue[index].Server = null;
>
> delete AsyncQueue[index].Server;
>
> AsyncQueue[index].ThisElement = null;
>
> delete AsyncQueue[index].ThisElement;
>
> AsyncQueue[index] = null;

You don't need to call abort() or any of the 4 lines after that.
It looks like you may actually need to set .Server and .ThisElement =
null though frankly I'm not sure why.
> CollectGarbage();

CollectGarbage won't solve your problems. It is only useful in
debugging as it forces the garbage collector to run at a known point.


I simply threw it in to see if memory was actually being deallocated.
Unfortunately, nothing really changed.
Aside from executing code too many times (the f() function is called 3
times per HTTP request and you loop through each item in your array),


How can I necessarily avoid calling f three times, however? Attaching f to
onreadystatechange basically guarantees that this thing is going to get
called every time.

Ideally, I would have liked a way in "f" to determine which server object
fired the onreadystatechange event, but no information comes back from
onreadystatechange to indicate this, hence my convoluted attempts at
resolving things.


See below.
there doesn't appear to be any problems noticable at first glance.
But this isn't your actual code, is it? It doesn't make much sense to
make HTTP requests but do nothing with the results....


You're correct. However, even this code (without anything notable in
function "f", which would do something w/ the results) leads to memory
leaks. If I simulate an environment where, say, 400 of these requests are
made, the memory piles up and piles up and eventually I have IE using 156
megabytes of memory.

Unfortunately, although there don't *seem* to be any problems noticeable
(that's what I thought too, other than some semi-inefficient ways of going
through the asynclist) the memory allocations for this are enormous when 200
or so requests go through.


Whenever you use nested functions, a closure is created, giving the
enclosed function access to all of the outer function's arguments and
local variables. This is a common source of memory leaks. The
problem comes down to how relatively easy it is to create circular
references when you don't realize what is really going on. The
JScript garbage collector is capable of breaking circular references
between any number of JScript objects, but it cannot break a circular
reference where the chain includes an external object like an element
in IE or a COM object.

So, the point is basically, try not to mix nested functions and DHTML
and/or ActiveX because you might end up with a circular reference that
cannot be broken and, therefore, a memory leak.

This is an example of a function that leaks memory...
function omicron()
{
var x = MakeNewDiv();
x.foo = epsilon;
function epsilon()
{
...
}
}
The circular reference is:
x --> div --> epsilon --> x

That said, the only way to pass data to your onreadystatechange
handler is to use a closure. This example doesn't leak...

AsyncQueue = new Array();
asyncsRunning = 0;

function Init()
{
for (var i=0; i<500; i++)
{
AsyncRequestStart("", "id" + i);
}
}

function AsyncRequestStart(value, id)
{
var index;
var requestInfo = new Object();

index = AsyncQueue.length;
AsyncQueue.push(requestInfo);

// requestInfo.ThisElement = document.getElementById(id);
requestInfo.Server = new ActiveXObject("Msxml2.XMLHTTP");
requestInfo.Server.onreadystatechange = function () {
AsyncRequestComplete(index);
};
requestInfo.Server.open("GET",
"http://localhost/MyCompany/data.metadata?text=" + value, true);
requestInfo.Server.send(value);
asyncsRunning++;
}

function AsyncRequestComplete(index)
{
var requestInfo = AsyncQueue[index];
Log(index + ": readyState=" + requestInfo.Server.readyState);
if (requestInfo.Server.readyState == 4 /*FINISHED*/)
{
asyncsRunning--;
UpdateStatus();

// requestInfo.ThisElement = null;
requestInfo.Server = null;
delete AsyncQueue[index];
}
requestInfo = null;
}

function Log(s)
{
window.status = s;
}

function UpdateStatus()
{
document.body.innerText = "Pending Requests: "
+ asyncsRunning;
}

Regards,
Steve
--
Please post questions to the newsgroup; everyone benefits.
This post is provided "AS IS" with no warranties, and confers no rights
Sample code subject to http://www.microsoft.com/info/cpyright.htm
Jul 20 '05 #4

"Steve van Dongen [MSFT]" <st*****@online.microsoft.com> wrote in message
news:33********************************@4ax.com...
It looks like you may actually need to set .Server and .ThisElement =
null though frankly I'm not sure why.
I thought I had read something about references to the DOM causing leaks in
other's applications. (Part of it is just my paranoia in Javascriptabout
setting everything to null once I am done with the objects).

[explanation of closures and circular references]
See, I figured that *might* have been the problem and thus rearchitected
things to pull "f" out of the closure. However, that still didn't do
anything in terms of the memory usage. (see below where I reply to your
example)
That said, the only way to pass data to your onreadystatechange
handler is to use a closure. This example doesn't leak...


Thanks for your example! However, running your example through tresting and
looking at IE's memoery usage before and after:
IE before Init() is called:

Physical Memory: 14944 K
Peak Memory Usage: 14,944 K
Virtual Memory: 6,640 K

IE after Init() finishes:
Physical Memory: 23,880 K
Peak Memory Usage: 25,472 K
Virtual Memory: 16,872 K

And, just for kicks, I jacked up your Init function to loop 4,000 times
instead of just 500. Here were my results after it finished:

Physical Memory: 66,830 K
Peak Memory Usage: 92,104 K
Virtual Memory Usage: 73,104 K

This memory usage does not go away until I close IE (it stays even when
navigating to other sites). This is the memory leak I am referring to,
which now you have caught as well!

Therein lies my problem...?

Thanks,

-Justice
Jul 20 '05 #5
On Sun, 30 Nov 2003 18:20:15 GMT, "Justice" <ju**********@hotmail.com>
wrote:

"Steve van Dongen [MSFT]" <st*****@online.microsoft.com> wrote in message
news:33********************************@4ax.com.. .
That said, the only way to pass data to your onreadystatechange
handler is to use a closure. This example doesn't leak...


Thanks for your example! However, running your example through tresting and
looking at IE's memoery usage before and after:
IE before Init() is called:

Physical Memory: 14944 K
Peak Memory Usage: 14,944 K
Virtual Memory: 6,640 K

IE after Init() finishes:
Physical Memory: 23,880 K
Peak Memory Usage: 25,472 K
Virtual Memory: 16,872 K

And, just for kicks, I jacked up your Init function to loop 4,000 times
instead of just 500. Here were my results after it finished:

Physical Memory: 66,830 K
Peak Memory Usage: 92,104 K
Virtual Memory Usage: 73,104 K

This memory usage does not go away until I close IE (it stays even when
navigating to other sites). This is the memory leak I am referring to,
which now you have caught as well!


Sounds like you're measuring at different states. Before Init() is
called there are 0 pending requests; when Init() is complete there are
500 (or 4000) pending requests. You have to measure when the pending
request count reaches 0 again.

When I was testing my code I found that when I refreshed the page the
memory usage before and after was pretty consistent. Adding
CollectGarbage() at the end made it a little more consistent which is
what I'd expect. Another thing I noticed was that on the first run
memory usage after all the requests had completed was higher than at
the beginning. I suspect the discrepancy is the result of IE delay
loading some libraries and not indicative of a memory leak caused by
the script.

Regards,
Steve
--
Please post questions to the newsgroup; everyone benefits.
This posting is provided "AS IS" with no warranties, and confers no rights.
Sample code subject to http://www.microsoft.com/info/cpyright.htm
Jul 20 '05 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: Mark | last post by:
Hi all i was just wondering if you help. I have to send a cgi request to a company using xmlhttp request. They reply back with a line of info but when you view the internet explorer source code...
7
by: Fabri | last post by:
I'm trying to develop a way to include static files in htm pages with javascript. I'm trying to use XMLHTTP object this way: ...
9
by: fochie | last post by:
Greetings, I'm having a problem when I try to GET a file from my server via xmlhttp when using Mozilla. With IE I can get any type of file fine, get/display headers fine, etc. With Mozilla,...
5
by: warteschlange | last post by:
i want to postload javscript from another javascript. This works fine in firefox and IE6 for macIE i can use an Iframe to load the code and inject it with insertAdjacentHTML The problems arise...
1
by: mirandacascade | last post by:
I recognize that this question is not about javascript per se...it is more about xmlhttp...posting the question at this site because it appears as though this site has many posts related to xmlhttp...
1
by: wkerplunk | last post by:
Below is what I have build with several different languages. It works great but I need help, I am stuck. When you click on an item in the dropdown autocomplete div it does a mousedown function...
4
by: sirjohnofthewest | last post by:
If I possessed the power to sway the mind of every user in the world to delete all forms of Internet Explorer I would die a happy man. Hi guys, I frequently visit this site to get answers to my...
2
by: trpost | last post by:
Is it possible to execute javascript as passed in xmlHttp.responseText Here is what I am doing: search.js var xmlHttp xmlHttp=GetXmlHttpObject() var url="search.php"...
0
by: DolphinDB | last post by:
The formulas of 101 quantitative trading alphas used by WorldQuant were presented in the paper 101 Formulaic Alphas. However, some formulas are complex, leading to challenges in calculation. Take...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
0
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
0
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.