Hi,
Just make sure that nothing is continuing to reference the object, and
it will be available for garbage collection. When (or if) it gets
garbage-collected is up to the interpreter.
Sometimes it can be subtle when something continues to have a
reference to an object, particularly when creating closures[1]. For
instance, here's an Ajax call that expects to get a JSON response. The
code sets up a situation where all of the objects related to the Ajax
response (including the one(s) created by deserializing the JSON
string) are kept in memory, probably unnecessarily:
* * * *
new Ajax.Request("myurl", {
onSuccess: function(response) {
if (response.responseJSON && response.responseJSON.stuff) {
var container = $('container');
container.update({
bottom: response.responseJSON.stuff
});
$(container.lastChild).observe('click', function(event) {
// Handle it when the new stuff is clicked
});
}
}
});
* * * *
The culprit in the above is the click event handler. Since the click
event handler is a closure, it keeps a live reference to everything in
scope where it's defined -- and since the element keeps a reference to
the click handler and the click handler keeps a reference to
`response` and everything in it, all that stuff is stuck in memory and
cannot be garbage collected.
The above code can be refactored to prevent that, by making the click
handler *not* a closure over the response (e.g., define it elsewhere
and then just use it):
* * * *
new Ajax.Request("myurl", {
onSuccess: function(response) {
if (response.responseJSON && response.responseJSON.stuff) {
var container = $('container');
container.update({
bottom: response.responseJSON.stuff
});
$(container.lastChild).observe('click',
handleClickOnStuff);
}
}
});
function handleClickOnStuff(event) {
// Handle it when the new stuff is clicked
}
* * * *
The click event handler no longer closes over the Ajax response, and
so once the success handler has finished, nothing will continue to
have a reference to the response and it's all available for garbage
collection. The above also has the advantage of not creating a new
function each time the Ajax call is done; instead, you reuse the same
click handler function.
Alternately, you can use the "null out" approach, which looks like
this:
* * * *
new Ajax.Request("myurl", {
onSuccess: function(response) {
if (response.responseJSON && response.responseJSON.stuff) {
var container = $('container');
container.update({
bottom: response.responseJSON.stuff
});
$(container.lastChild).observe('click', function(event) {
// Handle it when the new stuff is clicked
});
response = undefined; // <== This is the change
}
}
});
* * * *
In the above, the click handler will continue to have a reference to
the `response` parameter, but you've broken that parameter's reference
to the `response` object, and so the click handler doesn't keep that
object (and the things it refers to) in memory. I don't like this
approach, but you see it done a lot, and like all tools it does have
its place in certain limited situations. It discourages reuse, though,
and still involves a memory impact every time you run it -- it creates
a new copy of the event handler and a new execution context for it --
but at least the large item referenced by `response` isn't kept
around.
None of this is remotely limited to JSON stuff. Change the call so it
returns text or HTML instead of JSON and change
`response.responseJSON.stuff` in the above to `response.responseText`
and you have the same problem -- the text will be kept in memory by
the click handler if the handler is a closure over the response.
When I first learned this about JavaScript and closures, I freaked out
a little bit. OMG! My functions must be keeping all kinds of rubbish
in memory! Ack! But don't worry, once you understand closures, you are
in complete control of what they do and don't keep references to --
and they're a wonderfully powerful tool in your toolkit.
[1] http://blog.niftysnippets.org/2008/02/closures-are-not-complicated.html
HTH,
--
T.J. Crowder
Independent Software Consultant
tj / crowder software / com
www.crowdersoftware.com
On Aug 25, 10:06 pm, chrysanthe m <[email protected]> wrote:
> Hello
> Is thee a way to remove a json object processed by prototype client side?
> My objects are very large and will get larger so I must be frugal and clean
> up after each processing. Also is there a way to increase the size of the
> header to a maximum(what?). tia.
--
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 [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/prototype-scriptaculous?hl=en.