我有以下函数创建jQuery对话框并在其上设置jqGrid。 我的代码在IE 8中运行。
每次打开对话框时,我都会注意到浏览器的内存增加了大约30 MB。 当我关闭对话框时,这个内存不会被释放。
此代码在哪里泄露?
function ShowData() {
var gridID = "my_detail_grid";
var pagerID = gridID + "_pager";
var markup = $('<div style="display: none;">' +
'<input type="hidden" id="pclist_ownerID" name="pclist_ownerID" />' +
'<table id="' + gridID + '"></table>' +
'<div id="' + pagerID + '"></div>' +
'</div>');
var owner = $('#pclist_ownerID', markup);
markup.dialog({
autoOpen: false, modal: true, stack: true, resizable: false, position: 'center',
width: 860, height: 400,
close: function (event, ui) {
$(gridID).jqGrid('GridUnload');
$(this).dialog('destroy');
$(this).remove();
}
});
$.ajax({
url: 'MyWebService.asmx/GetAdditionalData',
type: "post",
dataType: "json",
async: false,
data: JSON.stringify({ objectID: objectID }),
contentType: "application/json; charset=utf-8",
success: function (data) {
var title = titlePrefix + data.d.objectname + " - " + data.d.period;
markup.dialog("option", "title", title);
owner.val(data.d.workgroupid);
}
});
markup.dialog('open');
var grid = $('#' + gridID);
grid.jqGrid({
url: 'MyWebService.asmx/MyMethod',
colNames: [
'Field1',
'Field2',
'Field3'
],
colModel: [
{ name: 'Field1', index: 'Field1', width: 120, sortable: false, align: 'left', search: true, template: colTextTemplate, searchrules: { required: false } },
{ name: 'Field2', index: 'Field2', width: 170, sortable: false, align: 'left', search: true, template: colTextTemplate, searchrules: { required: false} },
{ name: 'Field3', index: 'Field3', width: 170, sortable: false, align: 'left', search: true, template: colTextTemplate, searchrules: { required: false} }
],
serializeGridData: function (postData) {
if (postData.filters === undefined) postData.filters = null;
return JSON.stringify(postData);
},
jsonReader: {
id: "MyRecordID"
},
footerrow: false,
userDataOnFooter: true,
sortname: 'MyRecordID',
sortorder: "asc",
pager: $('#' + pagerID),
rownumbers: true,
gridComplete: function () {
//this method just enable or disable the add/edit/delete based on conditions
reconfigPermissions();
},
gridview: true,
autowidth: false,
shrinkToFit: false,
width: 830,
height: 264
})
.jqGrid('navGrid', '#' + pagerID,
{
add: true, addtitle: 'Add Record',
edit: true, edittitle: 'Edit Record',
del: true, deltitle: 'Delete Record',
refresh: false,
search: false, //searchtitle: 'Advanced search filters',
addfunc: function () {
// code for add
},
editfunc: function () {
// code for edit
}
},
{ /*default settings for edit*/ },
{ /*default settings for add*/ },
{
/* settings for delete*/
// define settings for Delete
mtype: "post", reloadAfterSubmit: true,
url: 'MyWebService.asmx/Delete',
resize: false,
serializeDelData: function (postdata) {
return JSON.stringify({ recordID: postdata.id });
},
afterSubmit: function (data, postdata) {
}
},
{},
{}
)
.jqGrid('navSeparatorAdd', '#' + pagerID, {})
.jqGrid('navButtonAdd', '#' + pagerID, {
caption: "", buttonicon: "ui-icon-search", position: "last", title: "Advanced search filters",
onClickButton: function () {
grid.searchGrid({
sopt: ['eq', 'ne', 'lt', 'le', 'gt', 'ge', 'bw', 'cn'],
closeOnEscape: true, multipleSearch: true, closeAfterSearch: true, recreateFilter: true
});
}
});
}
非常感谢你的帮助!
编辑:对此没有任何建议?
答案 0 :(得分:1)
所有听起来都很奇怪。 jqGrid工作不清理内存。尽管如此,我不认为在每次打开对话框后增加30 MB的内存只能由jqGrid解释。您使用的网格不包含rowNum
。因此将使用默认值20(请参阅the documentation)。您不使用loadonce: true
选项,因此用作网格中的URL的'MyWebService.asmx/MyMethod'
应返回大约20 * 4个单元格值(3列+ id列)。这样的响应和jqGrid创建的所有DOM结构都不能占用30 MB内存。
所以我认为问题的原因可能是jqGrid。您可以使用Fiddler,IE或Chrome的开发人员工具来跟踪HTTP流量。我们建议您验证'MyWebService.asmx/MyMethod'
和'MyWebService.asmx/GetAdditionalData'
的回复。可能是某些响应包含太多数据。减少数据并不能真正解决问题,但30 KB的内存泄漏将不会像30 MB大小的泄漏那么重要。顺便说一句,您可以使用userData
并刷新对话框的标题(在loadComplete
内创建相同的对话框选项“title”)。在你保存同步(async: false
???)Ajax调用的方式。
此外,我建议您将datatype
选项从"json"
更改为{临时,仅用于测试} "local"
。在这种情况下,不会对URL 'MyWebService.asmx/MyMethod'
发出请求,您可以验证方法的调用和填充网格数据是否是造成30 MB的主要问题。
您建议您另外使用jqGrid的deepempty: true
选项。
如果所有测试都显示jqGrid负责内存泄漏,那么您将不得不替换$(gridID).jqGrid('GridUnload');
调用以对jqGrid创建的所有DOM结构(单元格和行)进行递归清理。我希望不需要它。