DEMO Code
var _scope = this;
this.logJqGrid = logTable.jqGrid({ datatype: "local", colNames: [ NextGen.Lang.DeviceLogGraph.tableHeader.date, NextGen.Lang.DeviceLogGraph.tableHeader.value ], colModel:[ {name:'timestamp',index:'timestamp', width:60, align:'center',formatter : this.dateFormatter}, {name:'value',index:'value', width:40, align:'center'} ], autowidth: true, height: 'auto', hidegrid: false, forceFit: true, altRows : true, emptyrecords: "Nothing to display", // onSelectRow : function() // { // NextGen.Index.currentPage.onSelectRow(); // global object cuicle reference don't bring on memory leak // } /** * The following code will bring on memory leak * 1. onSelectRow : NextGen.Utils.scopeHandler( this.onSelectRow, this ) == (function(fn,scope){return function(){fn.call(scope);}})(fn,scope); * 2. var scope = this; onSelectRow : function(){scope.onSelectRow();} * */ onSelectRow : NextGen.Utils.scopeHandler( this.onSelectRow, this ) });
Issure code :
p, pin
$.fn.jqGrid = function(pin) { //pin is init config object if (typeof pin == 'string') { //var fn = $.fn.jqGrid[pin]; var fn = $.jgrid.getAccessor($.fn.jqGrid,pin); if (!fn) { throw ("jqGrid - No such method: " + pin); } var args = $.makeArray(arguments).slice(1); return fn.apply(this,args); } return this.each( function() { if(this.grid) {return;} var p = $.extend(true,{ grouping : false, ignoreCase : false, cmTemplate : {}, idPrefix : "" }, $.jgrid.defaults, pin || {});
init config info object pin's event handler will hold reference _scope ,and p has the same reference. _scope hold jqgrid return object ,it can access p/pin indirect, it bring on circularreference.
profile:
from snapshot ,we can find, two place hold memory can't free:
1. pin, init config object, it has a reference point onSelectRow
2. p, it has the copy of pin properties
resolve:
1. remove pin
p hold the copy of pin ,so pin is unavailable, we can remove it after copy the properties.
if(this.grid) {return;} var p = $.extend(true,{ }, $.jgrid.defaults, pin || {}); pin = null; // remove pin
2. remove all properties of p in GridDestroy, just need to remove function properties
GridDestroy : function () { return this.each(function(){ if ( this.grid ) { if ( this.p.pager ) { // if not part of grid $(this.p.pager).remove(); } for(var key in this.p) // remove all properties of p { this.p[key] = null; } this.p = null; try { $("#gbox_"+$.jgrid.jqID(this.id)).remove(); } catch (_) {} } }); },