Datatable memory leak under both IE and Chrome
Datatable memory leak under both IE and Chrome
Hi,
The application, I am developing, is using Datatable which binds the data and event dynamically. When monitored from Developer tool in internet explorer one can see an increase in the total memory usage after each successful server response (increases approx. 29-35 MB in total memory). I tried solutions to free the DOM objects and datatbles, using jquery functions like .remove(), .empty(), .detach(), and .destroy() but none stops the memory increase. Even destroying the datatable before a new request doesn't help. I also tried to delete the variables in the javascript, tried setting the variables to null, and tried setting the event bind to the datatable .off() nothing helps.
The code snippet from the js file is as follows:
function LoadData(isReset) {
var viewId = $jq('#ddlCategory').val();
if (viewId == 'undefined' || viewId == null || viewId == '') {
return false;
}
try {
//Clear the variables and remove the datatable
ClearFunction();
dtAjaxCall = $jq.ajax({
type: "POST",
url: "Ajax/WorkListAjax.aspx/GetData",
deferRender: true,
contentType: "application/json; charset=utf-8",
async: true,
dataType: "json",
timeout: 0,
headers: { Connection: 'keep-alive' },
data: JSON.stringify({
"viewId": viewId
}),
success: function (response) {
//Clear the variables and remove the datatable
ClearFunction();
result = response.d;
if (result.IsError) {
CustomConfirm("dialog-confirm", result.Message, "");
}
else if (result.Data != null) {
data01 = result.Data;
result.Data = null; //set the result.Data as null
tableHeaders = ''; //var to store Datatable headers
columns = []; //var to store Datatable columns
excludeFilters = [];//var to exclude the filters.
bulkOperation = data01.BulkOperation; //var to store if bulk operation is required
//Create the table header columns dynamically as configured in database
$jq.each(data01.Columns, function (i, val) {
if (val.HiddenColumn != "Y") {
tableHeaders += "<th>" + val.DisplayName + "</th>";
var col = { 'title': val.DisplayName, 'data': val.DataColumnName.toLowerCase() };
columns.push(col);
}
if (val.FilterColumn >= 0) {
excludeFilters.push(val.FilterColumn);
}
});
data = $jq.parseJSON(data01.Results); //result returned in ajax call
json = $jq.parseJSON(data01.WorkListJQStructure); //datatable configuration returned in ajax call
delete json["bAutoWidth"];
json.data = data;
json.columns = columns;
DisplayExportOptions(json.buttons, 'resultsTable', 'ulExportTo');
//Add checkbox for each row in the data table
dtColumnDefinition = function (data, type, full, meta) {
return '<input type="checkbox" data-id="' + data + '">';
}
json.aoColumnDefs[0].render = dtColumnDefinition;
//Ajax call to save the datatable state state
dtSaveState = function (settings, data) {
$jq.ajax({
type: "POST",
url: "Ajax/WorkListAjax.aspx/SaveState",
contentType: "application/json; charset=utf-8",
async: true,
dataType: "json",
data: JSON.stringify({ "viewId": viewId, json: data }),
"success": function () {
},
error: function (request, status, error) {
CustomConfirm("dialog-confirm", "An error occurred while processing your current request. Please try again", "");
}
});
}
//Try destroying the existing instance
if ($jq.fn.DataTable.isDataTable('#resultsTable')) {
$jq('#resultsTable').DataTable().destroy();
}
//Make the body empty
$jq('#resultsTable tbody').empty();
//Remove the datatable
$jq("#resultsTable").dataTable().remove();
//Datatable save state function call
json.stateSaveCallback = dtSaveState;
//Empty from the parent table of the datatable
$jq("#resultsTable_display").empty();
//Create the datatable header dynamically and add to the parent table
$jq("#resultsTable_display").append('<table id="resultsTable" class="display" style="width:100%;white-space: nowrap;"><thead><tr>' + tableHeaders + '</tr></thead></table>');
//bind the json and data to the datatable
SearchTable = $jq("#resultsTable").DataTable(json).rows().invalidate().draw();
//Set the event off before
$jq("#resultsTable").off();
//Set the event
$jq('#resultsTable').on('length.dt', function (e, settings, len) {
//code to set the height dynamically...
});
$jq("#resultsTable_display .dataTables_scrollHeadInner").css("width", "100%");
$jq("#resultsTable_display .dataTables_scrollHeadInner .dataTable").css("width", "100%");
BulkOpr(bulkOperation, SearchTable);
//reset the columns after binding the data
SearchTable.columns.adjust();
DataTableName = '#resultsTable';
$jq('#resultsTable').on('page.dt', function () {
info = SearchTable.page.info();
customHeight = 0;
customHeight = UserDefinedFields.CustomPageHeight(info, 40);
$jq('#Parent').attr('style', 'min-height:' + customHeight + 'px;');
});
$jq("a").removeClass("dt-button");
}
//set the variables null
json = null;
data01 = null;
data = null;
},
error: function (request, status, error) {
//do nothing...
}
});
return false;
}
finally {
//Clear the variables...
}
}
//----------------------------------------------
//method to clear the variables and datatables
function ClearFunction()
{
//make all variables null
dtAjaxCall = null;
resultSearchTable = null;
DataTableName = null;
info = null;
customHeight = null;
cells = null;
selected = null;
cBox = null;
clist = null;
dtSaveState = null;
result = null;
data01 = null;
tableHeaders = null;
columns = null;
excludeFilters = null;
bulkOperation = null;
data = null;
json = null;
dtColumnDefinition = null;
//clear dom objects
$jq("#resultsTable").dataTable().remove();
$jq("#resultsTable_display").dataTable().empty();
}
Please help!
Thanks!
Answers
It looks like you are doing the right thing form the above. We'd need a minimal, complete, and verifiable example showing the issue to be able to help. JSFiddle, CodePen and http://live.datatables.net can all be used if you can host the page yourself.
Allan