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 (_) {}
}
});
},