views:

539

answers:

1

Hi,

I have been tracking down a memory leak in my web app which dynamically removes and adds anchors which have cluetip tooltips attached and I think that I may have narrowed down the problem to the main closure in cluetip which attaches the cluetip to the node (line 32: var link = this, $this = $(this);).

I have been running the following script in SIEV with a modified version of jquery 1.3.2 with the following fix which allows the cluetip elements to be removed. However, the anchor nodes become orphaned as there is still 1 reference to them after the cluetip nodes are removed?

If I change line 32 of the cluetip source to the following for testing purposes: var link = $('br'), $this = $('br');

The anchors are freed but the 'br' nodes start building up.

Therefore, I was wondering if anyone knows how I can work around this problem? or if I am simply not releasing the resources correctly?

Attached Scripts and Source:

jQuery modification. After line 1247 insert the following before the closing curly brace (http://markmail.org/message/cfi4bvfjc3m6ww6k#query%3Ajquery%20memory%20leak%20in%20remove%20and%20empty+page%3A1+mid%3Atapc7zt3cwl6rw4f+state%3Aresults):

this.outerHTML = "";

Example Script:

<html> 
<head> 
    <link rel="stylesheet" type="text/css" href="jquery.cluetip.css"/> 


    <script type="text/javascript" src="jquery-1.3.2.js"></script> 
    <script type="text/javascript" src="jquery.cluetip.js"></script> 


    <script type="text/javascript"> 
            $(document).ready(function() { 
                    setInterval(resetCluetip, 1000); 
            }); 


            function resetCluetip() { 
                    $('a').each(function() { 
                            $(this).cluetip('destroy'); 
                            $(this).unbind().remove(); 
                    }); 


                    $('#cluetip*').unbind().empty(); 


                    $('body').html('<a href="#" class="contextMenu" title="title|body">anchor one</a><br>'); 


                    $('a').each(function() { 
                            $(this).cluetip({splitTitle: '|'}); 
                    }); 
            } 
    </script>
</head>
<body>
</body>
</html>
+1  A: 

So here are a few comments:

  • First off, what this script does makes no sense to me... resetting the cluetips and the contents of the page every second. Why not just update the title attribute with new information then refresh the cluetip or set the cluetip attribute ajaxCache: false if you are getting the updates via ajax?
  • Using .remove() on an object should remove it from the DOM and also unbind any references, so you shouldn't need to use .unbind().remove(); or .unbind().empty();
  • Wildcards don't work with IDs this way $('#cluetip*') a better way to do this is to use a selector attribute filter like this $('div[id*="cluetip"]')
  • I couldn't duplicate the memory leak.
fudgey
The script is is simply a test container for what my production application does to highlight the problem.In my production application we have anchor tags that represent documents which can be added or removed by the users therefore, when they are added or removed the cluetips needs to be added or removed.Unfortunately, it seems that the remove cannot remove the references to the anchor due to the closure (http://www.ibm.com/developerworks/web/library/wa-memleak/) which causes the leak.What version of I.E. did you use to test this? As I.E. 6 and 7 cannot deal with this kind of leak
Andrew
Thanks for the reminder on wildards. The other cluetip objects seem to get cleaned up with the way I have it now. But that might be most likely because I am cleaning up the parent object which has the id "cluetip".
Andrew