Javascript as a language certainly cannot leak memory,
because there is no way to manually allocate and
deallocate memory.
If Java-like memory management systems would exclude memory leaking as
such: the world would program on nothing but Java long ago :-)
Such systems can perfectly leak as well, the difference is in the
mechanics and in the definition itself of "leaked memory". We can
compare C-like memory management and Java-like memory management
respectively with the garbage removal in a building and in a private
house. In a flat we put all trash into trash can and manually dump it
into collector. The question of "when the trash will be removed?" has
no application to the situation: it is removed at the moment of
dumping. In a private house there is a "garbage day" each week when we
have to place our container at the right place at the right position.
We cannot tell for sure when the track will come: at 6am, 7am or
afternoon. The only thing that should bother us is to place the
container properly. If it is placed properly, it will be eventually
emptied up sometime during the trash pickup day.
It seems that many C-ground programmers just refuse to fully accept
such memory management. Theoretically they know about it, but as soon
as it comes to the practical development they just come back to what
they used to. This is why I guess 99% of "memory monitoring" software
for javascript is written from C positions and therefore 100% useless
for javascript.
In javascript memory management is *automated* which means that lesser
you put your sneeky hands into it - better it works :-)) :-|
It also impossible to have a leak with fully dereferened objects. They
may remain in the memory for uncertain period of time but it is not a
leaked memory. A memory leak occurs then Garbage Collector cannot mark
a scavenger as free for removal: which means that despite the program's
author may think the opposite, there is at least one reference left
somewhere to this object. The "circular reference leak" in IE is a
classical sample of such situation.
>From the explicit memory management actions I can name only one:
dereferencing of an unused object by either setting it to null or by
using delete operator. (Important: setting a reference to undefined
value doesn't free the reference: it will remain a valid reference with
a valid explicitly assigned value). If all references to the object are
removed ("trash container is placed into the right position in front of
the house"): then in the next scan Garbage Collector will mark the
relevant scavenger (internal representation of the object) as garbage
collection available. Garbage Collector works in a "double stage" mode:
i) on the first stage it marks unused scavengers, ii) on the second
stage it actually destroys the heaps. Depending on available free
memory, intensity of the program process etc. the second stage may
happen a minute or an hour later: or it will never happen at all until
exit: if available memory is big and/or memory usage remains low. That
is NORMAL, that is OK, that was made this way for maximum optimization
(I feel like scream it out loud sometimes :-)
In Java itself you can *ask* the system to expedite the process by
using System.gc() method. It doesn't enforce the garbage collection, it
only trigs free memory check and it removes the garbage *if* the free
memory level is getting low. So most of the time System.gc() does
nothing useful except bringing a false feeling of peace to the
programmer who uses it.
JScript (but not other javascript versions AFAIK) can be more rude: by
using undocumented CollectGarbage() method you can *enforce* an
immediate removal of all scavengers marked as free to remove. But why
would you need it in a practical application? Are we so terribly short
on memory to sacrifice the execution speed for 100Kb - 500Kb ?
Internal invocation in javascript (at least in JScript) is made as
simple as a moo-cow: there are not any virtual table bindings and
dispid's are not cached. It means that in the code like:
for (var i=0; i<10000; ++i) {
foobar.foo.bar();
}
the dispatcher will request 10000 times a reference to the object
matching "foobar.foo.bar" string in the names table. That may seem as
ineffective, but it allows to keep the engine small and clean and it
allows many nice javascript'ish things like a function referencing
other function which doesn't exists yet at the moment of referencing.
In application to the memory management it means once again that you
have neither tasks nor worries but deference unused objects properly:
if you have objects needed at the beginning and never needed anymore
from some point to the end. If you have not such objects, then you can
do your best for the memory management by *doing nothing* and by
letting the automation to make the job for you.
Used memory growth by itself is *meaningless* in Java-like memory
systems. It can use say 9Mb out of allowed 10Mb while doing foo = 2 *
2; - and at the next moment it will start doing matrix transformations
and the memory usage will fail to 100Kb.