DOM elements not getting destroyed? Memory keeps rising....
DOM elements not getting destroyed? Memory keeps rising....
First off; thanks for the amazing plugin. Your work is much appreciated...
I've been tearing my hair out trying to figure out why the memory usage of my page keep climbing into perpetuity every time I use fnreloadjax to refresh the contents of my datatable. Memory keeps climbing until eventually the page shows the "he's dead jim!" message in Chrome (usually after about a full day and swelling to 1 GB+ of memory usage). I'd assume this is because DOM elements aren't getting destroyed properly... or something? Anything you can do to even point me in the right direction would be sincerely appreciated....
Here's the code for the table initialization:
[code]
var oTable = $('#internalnotes').dataTable( {
"bJQueryUI": true,
"bPaginate": false,
"bDestroy": true,
"bDeferRender": true,
"aaSorting": [[ 2, "desc" ]],
"aoColumns": [
{ "sType": "numeric", "bSearchable": false,
"bVisible": false },
{ "iDataSort": 0, sClass: "alignCenter", "sWidth": "10%" },
{ "sType": "date", "sWidth": "15%", "bVisible": false },
{ type: "select", values: [ 'Dept1', 'Dept2', 'Dept3'], sClass: "alignCenter", "sWidth": "10%" },
{"sClass": "alignLeft", "sWidth": "70%" },
],
"sAjaxSource": "GetNewNotes.php?CustomTickers=<?php echo $CustomTickers . "&username=" . $username . "&usertype=" . $usertype?>"
} )
.columnFilter({
aoColumns: [
null,
null,
null,
{ type: "select", values: [ 'Dept1', 'Dept2', 'Dept3', 'Dept4'] },
null
]
});
[/code]
and here is the code that goes within a repeating setTimeout function (loads every 20 seconds) to get the new content (it has some extra code for deciding whether or not to show a notification -- i.e. if a new item has been added)
[code]
var NoteItemCountPre = 0;
var NoteItemCountPost = 0;
$.fn.dataTableExt.oApi.fnReloadAjax = function ( oSettings, sNewSource, fnCallback, bStandingRedraw )
{
NoteItemCountPost = oTable.fnGetData().length;
if ( typeof sNewSource != 'undefined' && sNewSource != null ) {
oSettings.sAjaxSource = sNewSource;
}
// Server-side processing should just call fnDraw
if ( oSettings.oFeatures.bServerSide ) {
this.fnDraw();
return;
}
this.oApi._fnProcessingDisplay( oSettings, true );
var that = this;
var iStart = oSettings._iDisplayStart;
var aData = [];
this.oApi._fnServerParams( oSettings, aData );
oSettings.fnServerData.call( oSettings.oInstance, oSettings.sAjaxSource, aData, function(json) {
/* Clear the old information from the table */
that.oApi._fnClearTable( oSettings );
/* Got the data - add it to the table */
var aData = (oSettings.sAjaxDataProp !== "") ?
that.oApi._fnGetObjectDataFn( oSettings.sAjaxDataProp )( json ) : json;
var NoteItemCountPre = 0;
for ( var i=0 ; i NoteItemCountPost)
{
ShowNotification();
$.titleAlert('New Blog Post', {interval:1000, originalTitleInterval:200});
}
oSettings.aiDisplay = oSettings.aiDisplayMaster.slice();
if ( typeof bStandingRedraw != 'undefined' && bStandingRedraw === true )
{
oSettings._iDisplayStart = iStart;
that.fnDraw( false );
}
else
{
that.fnDraw();
}
that.oApi._fnProcessingDisplay( oSettings, false );
/* Callback user function - for event handlers etc */
if ( typeof fnCallback == 'function' && fnCallback != null )
{
fnCallback( oSettings );
}
}, oSettings );
};
var NoteItemCountPost = NoteItemCountPre;
[/code]
this is what the setTimeout function looks like:
[code]
var reloadNotes = function(){
clearTimeout(timeoutId);
oTable.fnReloadAjax( 'GetNewNotes.php?CustomTickers=<?php echo $CustomTickers ?>&username=<?php echo $username ?>&usertype=<?php echo $usertype ?>');
startCountdown(); // Otherwise it will just run once
};
[/code]
and the countdown that starts the timer
[code]
var timeoutId = 0;
function startCountdown() {
clearTimeout(timeoutId)
timeoutId = setTimeout(reloadNotes, 20000);
};
[/code]
I've been tearing my hair out trying to figure out why the memory usage of my page keep climbing into perpetuity every time I use fnreloadjax to refresh the contents of my datatable. Memory keeps climbing until eventually the page shows the "he's dead jim!" message in Chrome (usually after about a full day and swelling to 1 GB+ of memory usage). I'd assume this is because DOM elements aren't getting destroyed properly... or something? Anything you can do to even point me in the right direction would be sincerely appreciated....
Here's the code for the table initialization:
[code]
var oTable = $('#internalnotes').dataTable( {
"bJQueryUI": true,
"bPaginate": false,
"bDestroy": true,
"bDeferRender": true,
"aaSorting": [[ 2, "desc" ]],
"aoColumns": [
{ "sType": "numeric", "bSearchable": false,
"bVisible": false },
{ "iDataSort": 0, sClass: "alignCenter", "sWidth": "10%" },
{ "sType": "date", "sWidth": "15%", "bVisible": false },
{ type: "select", values: [ 'Dept1', 'Dept2', 'Dept3'], sClass: "alignCenter", "sWidth": "10%" },
{"sClass": "alignLeft", "sWidth": "70%" },
],
"sAjaxSource": "GetNewNotes.php?CustomTickers=<?php echo $CustomTickers . "&username=" . $username . "&usertype=" . $usertype?>"
} )
.columnFilter({
aoColumns: [
null,
null,
null,
{ type: "select", values: [ 'Dept1', 'Dept2', 'Dept3', 'Dept4'] },
null
]
});
[/code]
and here is the code that goes within a repeating setTimeout function (loads every 20 seconds) to get the new content (it has some extra code for deciding whether or not to show a notification -- i.e. if a new item has been added)
[code]
var NoteItemCountPre = 0;
var NoteItemCountPost = 0;
$.fn.dataTableExt.oApi.fnReloadAjax = function ( oSettings, sNewSource, fnCallback, bStandingRedraw )
{
NoteItemCountPost = oTable.fnGetData().length;
if ( typeof sNewSource != 'undefined' && sNewSource != null ) {
oSettings.sAjaxSource = sNewSource;
}
// Server-side processing should just call fnDraw
if ( oSettings.oFeatures.bServerSide ) {
this.fnDraw();
return;
}
this.oApi._fnProcessingDisplay( oSettings, true );
var that = this;
var iStart = oSettings._iDisplayStart;
var aData = [];
this.oApi._fnServerParams( oSettings, aData );
oSettings.fnServerData.call( oSettings.oInstance, oSettings.sAjaxSource, aData, function(json) {
/* Clear the old information from the table */
that.oApi._fnClearTable( oSettings );
/* Got the data - add it to the table */
var aData = (oSettings.sAjaxDataProp !== "") ?
that.oApi._fnGetObjectDataFn( oSettings.sAjaxDataProp )( json ) : json;
var NoteItemCountPre = 0;
for ( var i=0 ; i NoteItemCountPost)
{
ShowNotification();
$.titleAlert('New Blog Post', {interval:1000, originalTitleInterval:200});
}
oSettings.aiDisplay = oSettings.aiDisplayMaster.slice();
if ( typeof bStandingRedraw != 'undefined' && bStandingRedraw === true )
{
oSettings._iDisplayStart = iStart;
that.fnDraw( false );
}
else
{
that.fnDraw();
}
that.oApi._fnProcessingDisplay( oSettings, false );
/* Callback user function - for event handlers etc */
if ( typeof fnCallback == 'function' && fnCallback != null )
{
fnCallback( oSettings );
}
}, oSettings );
};
var NoteItemCountPost = NoteItemCountPre;
[/code]
this is what the setTimeout function looks like:
[code]
var reloadNotes = function(){
clearTimeout(timeoutId);
oTable.fnReloadAjax( 'GetNewNotes.php?CustomTickers=<?php echo $CustomTickers ?>&username=<?php echo $username ?>&usertype=<?php echo $usertype ?>');
startCountdown(); // Otherwise it will just run once
};
[/code]
and the countdown that starts the timer
[code]
var timeoutId = 0;
function startCountdown() {
clearTimeout(timeoutId)
timeoutId = setTimeout(reloadNotes, 20000);
};
[/code]
This discussion has been closed.
Replies
[code]
$(document).on("click", "span.read-more", function () {
clearTimeout(timeoutId);
setTimeout( startCountdown, 90000);
});
[/code]
Is there any way to free the memory despite having these events attached?
Allan
Interesting.... actually it appears that the problem does NOT go away. The DOM Node Count keeps increasing, alongside memory usage.... I tried removing all the .on event handlers and disabling the column filter plug-in, and it actually looks like memory usage (per Google Chrome's task manager) is increasing *faster*.
However, it does look like there is some type of garbage collection or DOM node destruction occurring about every 4-5 minutes now, because the DOM node count suddenly drops by ~10,000, only to continue its inexorable march upward. In other words, DOM nodes are getting destroyed, but only back to an elevated level.
Here's a screenshot of the increasing DOM count from Chrome's developer tools: http://imgur.com/nqfDbDh
Btw - why are you using both fnReloadAjax and bDestroy? Can you not just use fnReloadAjax?
Allan
Is there any way to just force destruction of the added DOM nodes? At a loss regarding why they just continue to hang around...
Thanks
They should be destroyed by the call to fnClearTable in fnReloadAjax - unless something else is holding a preference to them. An event handler for example.
Allan