| Page 1 of 2 | [ 11 posts ] | Go to page 1, 2 Next |
|
The following code results in a memory leak with detached dom subtrees holding references to javascript objects. They can be viewed in the chrome heap profiler. If you let this run, you will see that it quickly exhausts your browsers memory.
The basic datatable example from the examples page also exhibits this problem. Code: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"> <title>Basic Example</title> <style type="text/css"> /*margin and padding on body element can introduce errors in determining element position and are not recommended; we turn them off as a foundation for YUI CSS treatments. */ body { margin:0; padding:0; } </style> <link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.9.0/build/fonts/fonts-min.css" /> <link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.9.0/build/datatable/assets/skins/sam/datatable.css" /> <script type="text/javascript" src="http://yui.yahooapis.com/2.9.0/build/yahoo-dom-event/yahoo-dom-event.js"></script> <script type="text/javascript" src="http://yui.yahooapis.com/2.9.0/build/dragdrop/dragdrop-min.js"></script> <script type="text/javascript" src="http://yui.yahooapis.com/2.9.0/build/element/element-min.js"></script> <script type="text/javascript" src="http://yui.yahooapis.com/2.9.0/build/datasource/datasource-min.js"></script> <script type="text/javascript" src="http://yui.yahooapis.com/2.9.0/build/event-delegate/event-delegate-min.js"></script> <script type="text/javascript" src="http://yui.yahooapis.com/2.9.0/build/datatable/datatable-min.js"></script> <script type="text/javascript"> var counter = 0; var myDataTable; function populate() { var innerElement = document.createElement('div'); innerElement.id = 'inner'; document.getElementById('outer').appendChild(innerElement); var data = { bookorders: [ {id:"po-0167", date:new Date(1980, 2, 24), quantity:1, amount:4, title:"A Book About Nothing"}, {id:"po-0783", date:new Date("January 3, 1983"), quantity:null, amount:12.12345, title:"The Meaning of Life"}, {id:"po-0297", date:new Date(1978, 11, 12), quantity:12, amount:1.25, title:"This Book Was Meant to Be Read Aloud"}, {id:"po-1482", date:new Date("March 11, 1985"), quantity:6, amount:3.5, title:"Read Me Twice"} ] } var createTable = function() { var myColumnDefs = [ {key:"id", sortable:true, resizeable:true}, {key:"date", formatter:YAHOO.widget.DataTable.formatDate, sortable:true, sortOptions:{defaultDir:YAHOO.widget.DataTable.CLASS_DESC},resizeable:true}, {key:"quantity", formatter:YAHOO.widget.DataTable.formatNumber, sortable:true, resizeable:true}, {key:"amount", formatter:YAHOO.widget.DataTable.formatCurrency, sortable:true, resizeable:true}, {key:"title", sortable:true, resizeable:true} ]; var myDataSource = new YAHOO.util.DataSource(data.bookorders); myDataSource.responseType = YAHOO.util.DataSource.TYPE_JSARRAY; myDataSource.responseSchema = { fields: ["id","date","quantity","amount","title"] }; myDataTable = new YAHOO.widget.DataTable("inner", myColumnDefs, myDataSource, {caption:"DataTable Caption" + counter}); return { oDS: myDataSource, oDT: myDataTable }; }(); counter++; setTimeout("clear_data()", 100); } function clear_data() { myDataTable.destroy(); myDataTable = null; document.getElementById('outer').innerHTML = ''; start_test(); } function start_test() { populate(); } </script> </head> <body class=" yui-skin-sam"> <div id="top1"> <input type="button" onclick="populate();" value="Add Data" style="z-index: 5000;"> <input type="button" onclick="clear_data();" value="Clear Data" style="z-index: 5000;"> <input type="button" onclick="start_test();" value="Start Test" style="z-index: 5000;"> </div> <div id="outer"> </div> </body> </html> Last edited by edurbin on Fri Dec 02, 2011 6:09 am, edited 1 time in total. |
|
Since YUI 2 is now in maintenance mode I'm not sure that anybody will propose to make any bug fixes, at least not from the YUI team.
|
|
you must call method destroy() to free the resources taken by the DataTable. Wiping out the HTML it produces is not enough, you leave many other things behind. JavaScript knows nothing about destructors, it is up to you to call destroy()
|
|
Satyam wrote: you must call method destroy() to free the resources taken by the DataTable. Wiping out the HTML it produces is not enough, you leave many other things behind. JavaScript knows nothing about destructors, it is up to you to call destroy() See example above, I'm calling myDataTable.destroy() and then nulling out the object with the exact same behavior. Still growing in number of detached dom subtrees with javascript references and exhausts browser memory. |
|
As Todd says, there is not further work on YUI2. However, if you want to refresh the DataTable, you might do so keeping the same DataTable instance and refreshing the data.
This might help: http://www.satyam.com.ar/yui/#requery |
|
The datatable doesn't remove the event listeners properly on destroy(). There are several 'mouseout' and 'mouseover' event handlers lingering after destroy() is called. Commenting out the delegation for 'mouseenter' and 'mouseleave' eliminates the memory leak.
|
|
There's a problem with the delegates[] array that is leaking in event-delegate. When we add a delegate we push an item on to the delegates[] array. When an item is removed it finds the first index that matches that event in the delegates array and then does an array splice, only removing the first element it finds instead of all elements in the array even though we may have added 6 events to different subcomponents of the container as in the case of the datatable.
|
|
Eric,
Thanks for the patch. That memory leak has been a major problem for us since our ScrollingDataTables are large. I had to manually cut in your new event-mouseenter module as well as the changes to destroy (we are on an intranet and the import request will take longer than I'm willing to wait), but your remove function never gets called. Are there any other changes that need to be made? Can you verify that the remove function gets called? Thanks, Sean |
|
No, I don't think it does. I think remove() is only called when removing listeners, not when calling removeDelegate(). It should be calling the removeDelegate() function on destroy() and removing the events that were delegated on initialization.
|
| Page 1 of 2 | [ 11 posts ] | Go to page 1, 2 Next |
| You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum |
© 2006-2013 Yahoo! Inc. All rights reserved.
All code on this site is licensed under the BSD License unless stated otherwise.
About This Site · Security Contact Info
Powered by phpBB® Forum Software © phpBB Group