Loading ...
Sorry, an error occurred while loading the content.

Re: Yahoo best coding practices to avoid memory leaks

Expand Messages
  • bubbarubadub
    Thanks for the help! I look forward to the YUI blog update. I found Crockford s page helpful, and I also came across a coding guideline on another
    Message 1 of 5 , Sep 1, 2006
    • 0 Attachment
      Thanks for the help! I look forward to the YUI blog update. I found
      Crockford's page helpful, and I also came across a coding guideline
      on another developer's website that I have found very helpful:

      http://weblogs.java.net/blog/gmurray71/archive/2006/03/javascript_reco
      .html

      Thanks again,
      Randall


      --- In ydn-javascript@yahoogroups.com, Isaac Schlueter
      <isaac_schlueter@...> wrote:
      >
      > Randall,
      >
      > This is a great question, and a topic that has a lot of mysticism
      surrounding it. Like most Javascript issues, there's been a lot of
      very bad "authoritative" suggestions.
      >
      > First of all, if you don't use a polling mechanism of some kind,
      AJAX applications will leak memory like a bucket with no bottom. Use
      the YUI connection library for Ajax, and never look back. It's
      brilliant, and very easy to use.
      >
      > A good discussion on memory leaks and why and how they happen:
      http://www.crockford.com/javascript/memory/leak.html
      > The claim that closures cause memory leaks is, as Crockford
      says, "deeply wrong." Closures are fine, and have nothing to do with
      the problem.
      >
      > The problem happens when you have a Javascript object and DOM
      object that refer to one another in a cycle. IE can't figure out
      when it should reclaim the memory, so it doesn't ever do it.
      >
      > For example, this will cause a leak:
      > <script>
      > (function(){
      > var obj={b:document.body};
      > document.body.o=obj;
      > })();
      > </script>
      > If you set either obj.doc.body or body.o to NULL, then you'll
      break the circular chain, and IE will reclaim the memory.
      >
      > The cycle doesn't have to be so small. Even a chain of many steps
      can cause a leak if it is not broken. This will cause a leak, too:
      > <script>
      > (function(){
      > var d={b:document.body}
      > var obj={doc:d}; // obj.doc.body === document.body
      > document.body.o=obj;
      > })();
      > </script>
      >
      > The simplest way to ensure that you will never have a memory leak
      is to simply never have circular reference chains that cross between
      Javascript and DOM space. Make sure that you always have Javascript
      objects refer to DOM objects, and never the other way round, or vice
      versa.
      >
      > However, it's sometimes extremely convenient to have circular
      link. Consider this example:
      >
      > <script>
      > (function(){
      > var doSomething=function(e) {
      > this.innerHTML='did something!';
      > this.object.doSomethingElse(this.customPropertyOfSomeKind);
      > };
      > myDomNode.object=new myObject();
      > myDomNode.customPropertyOfSomeKind={some:'data object'};
      > YAHOO.util.Event.addListener(myDomNode,'click',doSomething);
      > })();
      > </script>
      >
      > Now, if myObject has any reference to myDomNode (even if it refers
      to something that refers to something else ... that refers to
      myDomNode), you'll leak memory.
      >
      > So, how to fix this?
      >
      > First, be aware when you're doing things that may cause a leak. If
      it's not a very big gain in code simplicity, then figure out another
      way around. If you're hanging a lot of Javascript objects onto DOM
      objects, there's a big chance of a leak creeping in. Personally, I
      try to make sure that all my references go from JS-->DOM and not the
      other way around. If the references are always one-way, then there's
      no chance of a leak. Also, we've seen performance issues with
      hanging too much stuff on DOM nodes if the page is big and
      complicated (that's anecdotal, and I don't have any hard numbers, so
      take it for what it's worth.)
      > If you understand how they work and why they happen, you can save
      yourself a lot of time later on tracking them down.
      >
      > Second, test your code with Drip.
      > http://outofhanwell.com/ieleak/index.php?title=Main_Page
      > I can't possibly stress how important this is. Even if you've done
      everything right, it's easy to overlook circular references if the
      code gets sufficiently complex. Even small memory leaks can add up.
      >
      > Third, if you must cause circular references in your code, be
      responsible about it. Save a reference to each afflicted DOM node,
      and break the cycles on window unload.
      > <script>
      > (function(){
      > var unLoaders=[];
      > myDomNode.object=new myObject(); // <--- let's say that this
      creates a leak somewhere
      > unLoaders.push(myDomNode); // <--- save it for later
      > var unload=function(){
      > for(var i=unLoaders.length-1;i>-1;i--){
      > unLoaders[i].object=null; // <--- break the cycle
      > }
      > };
      > YAHOO.util.Event.addListener(window,'unload',unload);
      > })();
      > </script>
      >
      > So, why do AJAX apps leak memory so badly if you don't use the yui
      Connection library? Consider the "typical" XHR code pattern:
      > <script>
      > (function(){
      > var x=getXHRobject();
      > x.onreadystatechange=function() {
      > if(x.readystate==4){
      > // do something.
      > }
      > };
      > })();
      > </script>
      > The XmlHttpRequest object is treated in Javascript much like a DOM
      node. If you attach an onreadystatechange handler to it, you've
      created a circular loop. The standard means of breaking these chains
      won't work. The YUI connection lib polls the object's readystate
      until it is done, and then calls your success function. (If it times
      out or gets an error, it calls your failure function.) Since there's
      no onreadystatechange listener, there's no circular reference, and
      thus, no memory leak.
      >
      > --
      > Isaac Z. Schlueter
      > Webdev, Yahoo! Games
      >
      >
      > ----- Original Message ----
      > From: bubbarubadub <randall.toepfer@...>
      > To: ydn-javascript@yahoogroups.com
      > Sent: Tuesday, August 22, 2006 10:20:54 AM
      > Subject: [ydn-javascript] Yahoo best coding practices to avoid
      memory leaks
      >
      >
      > Hello All,
      > I am developing a web application for my company that uses the
      Yahoo UI DD (Drag and Drop) class to place all content in movable
      modules. I am also using several Yahoo DOM classes.
      > My server requests all return raw html or JSON. I messed with
      Google's AJAXSLT and Sarissa and the documentation is subpar or the
      code is buggy.
      > The problem is my application is having a good bit of memory
      leaks. I've read several articles (such as this one on MSDN) online
      about the causes, but I'm still a bit mystified.
      > It seems one memory leak problem deals with replacing DOM nodes
      that have event handlers already attached. Another problem deals
      with functions declared within functions. It looks as if most of
      Yahoo's custom classes have this property.
      > Does Yahoo have any suggestions on how to deal with these issues,
      since I'm assuming they must be handled by any AJAX type web
      application?
      > Thanks for any help in advance, and I've been very pleased with
      the library!
      > Randall T.
      >
    Your message has been successfully submitted and would be delivered to recipients shortly.