VK wrote:
Adrian wrote: I'm sure the enemy is within! probably a circular reference but
its a lot of code! the issue is the memory shown as in use by
system monitor goes up each time the app is used.
It doesn't prove anything.
Given your record on recognising and labelling proof that doesn't mean
much in reality.
However, are you saying that because that is what you expect to see IE
doing? It would not surprise me as we have all seen how that
catastrophic mush that you write under the label 'JavaScript' has
cross-references so convoluted that you don't even understand the
relationships involved, and calling them 'circular' would be monumental
understatement.
Given you code I am not surprised that you would rather deny that this
issue exists; prefer to define it as something other than it is, or see
it as a misperception in others.
Didn't you learn your lesson with your defence of javascript
pseudo-protocol HREFs as completely safe and issue-free (if coded to
your satisfaction)? Indeed, have you yet recognised that the issues that
you were repeatedly told about while you blindly defended javascript
pseudo protocol HRFEs were real and significant?
The lesson there surly was that where everyone else recognises an issue
that you don't perceive at all it is you who will turn out to be
mistaken. The same is true here; the IE memory leak issue is real,
demonstrated, its cause and effect relationships certainly identified
and strategies for handling it, where necessary, designed and employed
by people who have understood what they are doing.
And I told you this last week. I realise that you are of the deluded
opinion that you know more about javascript than everyone else
contributing to this group (and don't let the constant stream of
evidence to the contrary get in the way of that delusion) but if you
elect not to believe me the least you could do is undertake some
research and see the many demonstrations of this phenomenon in action.
JScript engine uses an execution cache so once executed
blocks could be reused without extra parsing.
Another 'off the top of your head' fiction? It doesn't make sense to
talk of 'extra parsing' when javascript is required to be fully parsed
(except for - eval - and Function constructor code) and compiled into
its executable form prior to entering the global execution context.
Also as it was pointed out JScript / JavaScript are automated
memory management languages (like Java).
And JScript in IE allows the garbage collector to be explicitly
triggered through the available global - CollectGarbage - function
(rather than waiting for it to act in its own time) so it is possible to
directly test the result of JScript garbage collection on resource
allocation.
So for a long lasting complicated process a *normal* memory
usage picture should be:
1) start with the required amount (100-300Kb)
IE alone consumes considerably more memory than that.
2) over time (from 1min to 1hr) increase to 2-4Mb / 5-6Mb for
JScript.Net
3) after that stay on the reached level with +/- 20% fluctuations
This *normal* behavior (or the absence of such) can be observed
on any tools I mentioned in my previous post.
The extra 2-6 Mb overtime gain is not a leaked memory: these
are all kind of pre-compiled functions, 3rd libraries blocks,
intermediary DOM snapshots - briefly all kind of working
stuff used for performance optimisation.
The leak is only if:
1) You get IE alert "This process takes too many resources".
So a memory leak can be eliminate by increasing system resources? That
is no a logical definition of a memory leak.
2) IE gets non-responsive / frozen
3) IE crashes with no reason
There is no issue so long as code doesn't actually break the browser?
With criteria like that it is less than surprising that you write such
poor code.
4) After you closed *all* IE instances and left your desktop
for 10 min *minumum* some strange process is still running
?
5) Besides that you may have DDE handler leak - so say after your
edited an Excel table over GetObject you cannot run Excel anymore or
you cannot open the same file in Excel until you exit IE.
What I was hoping for is a monitor that would say these objects
have been created and are X in size, so I know where to look!
JScript allocates memory using the relevant VBScript module
(same as for Dim myVar w/o type specification), so all variables
are Variant - of the same size and structure as in VBScript.
Making this stuff up off the top of your head does no more than make you
look a fool.
You still missing to say which one of five above is applicable
to your situation
The above are irrelevant to anyone's situation.
Otherwise you are just another C++'er who wants one world
being ticking by the rules of another world :-)
Who are you to be criticising others? You disregard the rules that
define javascript and substitute your own tangled web of inconstant
fictions, including many notions adopted from misconceptions of other
languages.
Precedent suggests that even demonstrations of phenomena do not convince
you of their reality but in the hop that you will actually realise that
you don't know what you are talking about in this respect (at least) I
will post a demonstration of IE memory leak issue. Even if you are not
convinced at least it will leave the rational in no doubt that the issue
exists.
As some memory monitoring is not always that fine-grained the
demonstration strategy is to create an object with a string pro9perty
that is sufficiently big that un-garbage collected instances will be
evened even in tools as crude as System Monitor. The following HTML,
when loaded into IE provides 5 buttons:-
"Make Big Object" - creates an object with a large string
property, but then removes all references to that object
so it is free for garbage collection.
"Make and trap big Object" - creates the same big object
but also creates a DIV element and circular references
between the DIV and the JS object but simultaneously
clears all accessible references to the JS object and the
DIV.
"Break Circular References" - examines all DIVs and removes
any JS objects assigned to them (breaking the circular
references).
"Collect Garbage" - Runs the JScript garbage collector
immediately.
"Create Indestructible Big Object" - Creates the big object
and a DIV, with circular references between the two, but
never inserts the DIV into the DOM.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title></title>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
</head>
<body>
<script type="text/javascript">
function BigObject(){
var c, st = 'xxxx';
for(c = 0;c < 23;++c){
st += st; //double string size;
}
this.bulk = st;
}
BigObject.prototype.insertNode = function(){
document.body.appendChild(this.getNode());
};
BigObject.prototype.getNode = function(){
var self = this;
var div = document.createElement('DIV');
div.onclick = function(){return;};
return div;
};
function sequnce(callback, messge){
document.getElementById('out').innerText = messge;
setTimeout(callback, 40);
}
function makeBigObject(){
var temp = new BigObject();
temp = null;
document.getElementById('out').innerText =
'Object Created and References Cleared';
}
function makeTrapedBigObject(){
var temp = new BigObject();
temp.insertNode();
temp = null;
document.getElementById('out').innerText =
'Object Created with Circular References';
}
function makeIndistBigObject(){
var temp = new BigObject();
temp.getNode();
temp = null;
document.getElementById('out').innerText =
'Object Created with Isolated Circular References';
}
function breakCircles(){
var list, temp, c, len, count = 0;
if(
(list = document.getElementsByTagName('DIV'))
){
for(c = 0, len = list.length;c < len;++c){
temp = list[c];
if(temp.onclick){
temp.onclick = null;
++count;
}
}
}
document.getElementById('out').innerText =
(count +' Circular References Broken');
}
function colGarbage(){
CollectGarbage();
document.getElementById('out').innerText = 'Garbage Collected';
}
</script>
<div id="out">|||||||||</div>
<input type="button" value="Make Big Object"
onclick="sequnce(makeBigObject, 'Making Big Object');"><br>
<input type="button" value="Make and Trap Big Object"
onclick="sequnce(makeTrapedBigObject, 'Making and Trapping Big
Object')"><br>
<input type="button" value="Break Circular References"
onclick="sequnce(breakCircles, 'Breaking Circular References');""><br>
<input type="button" value="Collect Garbage"
onclick="sequnce(colGarbage, 'Collecting Garbage');"><br><br>
<input type="button" value="Create Indestructible Big Object"
onclick="sequnce(makeIndistBigObject, 'Createing Indestructible Big
Object');">
</body>
</html>
If the above page is loaded into IE with some form of memory monitor
operating clicking the "Make Big Object" button should show an evident
jump in memory consumption, but that object's references are free so the
object is immediately available for garbage collection. However, the
odds are good that IE will not garbage collect it for a while, so
clicking the "Collect Garbage" button will run the garbage collector
immediately, showing the allocated memory being returned to the system.
A similar reduction in consumed memory can also be observed by
navigating the page or re-lading the page (the implication being that
these two actions also trigger immediate garbage collection).
On the other hand clicking the "Make and trap big Object" button
increases the memory consumption but running the garbage collector will
not free this memory. And, more importantly, navigating away from the
page, or re-loading it also will not free this memory (as it does
without the circular references).
Without navigation or re-loading it is possible to click the "Break
Circular References" button ant then re-try the "Collect Garbage" button
to see that it is only the circular references that prevent the garbage
collection of the objects. And having used the "Break Circular
References" button navigation also frees the memory.
The issue here is not that the circular references prevent garbage
collection. They should as the DOM refers to the DIV so it cannot be
garbage collected, and so the JS object it refers to cannot be collected
either. The above illustrates that when the circular references are
removed the garbage collector does free the associated memory.
The issue here is rather that the circular references prevent garbage
collection when both the DIV and the JS object are unreferenceable in
the system (they refer to teach other but no external references to them
exist), even when a page is navigated away from or re-loaded. At that
point all of the objects involved, JS objects and DOM elements, become
unreferenceable and should be made available for garbage collection. But
the circular references prevent this garbage collection and the consumed
resources are never freed until IE is closed down.
The final button illustrates this issue within the same page. It creates
the big object and the DIV but it never inserts the DIV into the DOM, so
there are no available references to the JS object, and no references to
the DIV, but click the collect garbage button as much as you like and
this object will never be freed.
And that is the memory leak; consumed memory that should be expected to
be freed by garbage collected (and is in other brewer environments) is
not freed until the browser is closed down, and the cause of that
problem is circular references between DOM Elements and JS objects (of
one form or another).
Richard.