How the freeing up of resources should be done in jQuery? Is there any similar pattern?
jQuery will handle detaching event handlers that were attached to DOM elements using bind()
. As as a result there should be far fewer dangling references to DOM elements than if the developer was responsible for detaching event handlers themselves. However it does this only when the page unloads (i.e. the unload
event of the window
object). At that time it iterates its event cache (jQuery.cache
) and removes event listeners from elements, so that the browser can deduce that those elements are no longer referenced and reclaim the memory used by them.
There is no IDisposable
pattern per-say in jQuery. For your own objects, you must manage the disposing yourself. $(window).bind('unload', myCleanupFunction)
is a good start for this. There's nothing wrong with simply implementing a dispose
method on your objects, and calling it from within this cleanup function.
In broad terms, any object property or global variable that can/may have a circular reference should be given particular attention and destroyed (delete
or null
will suffice). Any references to DOM elements should be deleted or nulled. Any references to closures that closed around DOM elements should be deleted or nulled (event handlers are a common source of this pattern). If you remove elements from the DOM, do so with remove()
, which will automatically clear jQuery-bound event handlers from your elements.
How / when the dispose function is invoked by the ASP.NET Ajax library?
Like jQuery, the ASP.NET AJAX framework hooks into the unload
event of the window
object to perform some reference cleanup. Upon unload of the page Sys.Application.dispose
is called and the following occurs:
- If you have created a
pageUnload()
function in your application, that function is called
- It calls
dispose()
on any object that have you have registered with the application.
- It raises the Application
unload
event.
- It disposes the
ScriptLoader
instance.
ASP.NET AJAX components, controls and behaviors are by default registered automatically with the Sys.Application
object when the component is created (in the Sys.Component
constructor). Anything that inherits from IDisposable
is automatically registered with the framework upon instantiation (and placed in Sys.Application._disposableObjects
).
For objects that implement IDisposable
, the dispose()
method of your instance(s) is called (just like on the server). However you are still responsible for the actual free-ing of references (just like on the server).
IOW you do still need to take care to delete
or null
properties of your objects in the dispose
method. Same rules as jQuery apply here: any object property or global variable that can/may have a circular reference should be given particular attention, references to DOM elements should be deleted or nulled, references to closures that closed around DOM elements should be deleted or nulled.
Unlike jQuery however, ASP.NET AJAX will not automatically remove listeners you have bound with Sys.UI.DomEvent.addHandler
(aka $addHandler
) when the page unloads1. You must take care to do this yourself. The framework does provide Sys.UI.DomEvent.clearHandlers(element)
(aka $clearHandlers
) to do this easily however. You would call it in your dispose()
implementation and pass in any elements you have attached event listeners to with the framework.
IDisposable
in the client is meant more as a convenient place to put your "unload" code, and as a way for the code to self-document itself. I suspect most people are not creating and disposing many objects during the lifetime of their application, but rather creating them once on page load, and destroying them once on page unload.
Do we have to worry about memory leak if the page will be reloaded after a period of time?
A lot of effort has gone into profiling memory in DOM trees that do not unload often. In general, you don't have to worry too much if the page unloads often (this includes users navigating to other pages in your application). If it is a long-lived application (eg
gmail), you have to take great care wrt to memory leaks. With long-lived applications memory containment should not be viewed as a premature optimization, but a very distinct likelihood. Granted it's not going to be a performance bottleneck (in contrast to I/O say), but in today's applications the DOM is way too much of a beast to let the browser just handle it. However the management of this is very tricky to get right.
1This feature is coming to version 4.0 in the form of an autoRemove
parameter to Sys.UI.DomEvent.addHandler