javascript - 重复 jQuery 数据表 AJAX 调用的内存管理

标签 javascript jquery ajax memory datatables

我是 javascript 和 jQuery 的新手,所以请原谅我的问题描述中的任何不正确的措辞。

背景:我有一个网站,我正在使用 Datatables jQuery 插件,用于实时显示 SQL 表。 SQL 查询在 ASP.NET 中处理并作为 JSON 对象返回给客户端。现在,我只显示 ~500 条记录。

一旦数据表插件解析了 JSON 对象,我就会对表格单元格执行一些条件格式设置——因此,如果我正确理解该概念,可能会有一些繁重的 DOM 操作。我读到这可能是大量内存泄漏发生的地方,但我也认为 jQuery 在自行清理方面非常可靠。

我正在使用 setInterval 计时器定期更新数据表,以便实时显示更改。

我的问题:我网站的内存消耗失控。在每次 AJAX 调用(~每 2 秒)中,页面的内存使用量可能会增加 2MB。为了阻止这种情况,我安装了一个 idle plugin让 jQuery 检测用户何时在网站上处于事件状态 - 当用户空闲时,我将 AJAX 调用减少到大约每 1 小时一次。听说这样可以给浏览器更多的空间来进行垃圾回收。

我发现内存在事件时持续攀升,每 4 或 5 次调用略有下降,看起来好像正在执行一些垃圾收集。当用户空闲时减少 AJAX 调用时,内存不会攀升。下面,我粘贴了我的代码的精简版本(不包括一些不相关的片段)。我确信这不是最干净的代码——但如果有人可以提供一个指针来说明可能导致内存消耗的原因——或者我如何减少内存消耗,我将不胜感激。

提前致谢!

    //TIMER
    var updateFreq = 5000;
    var timer;

    setIdleTimeout(5000); // 5 seconds
    setAwayTimeout(50000); // 10 seconds
    document.onIdle = function() {
        clearInterval(timer);
        updateTable(3600000); //update once an hour
        //if (typeof (CollectGarbage) == "function") { CollectGarbage(); }
    }        
    document.onAway = function() { 
        clearInterval(timer);
        updateTable(3600000); //update once an hour
        //if (typeof (CollectGarbage) == "function") { CollectGarbage(); }
     }  
    document.onBack = function(isIdle, isAway) {
        clearInterval(timer);
        updateTable(5000); //update once every two seconds
    }
    //END TIMER

    var oTable;
    var oSettings;

$(document).ready(function() {
    oTable = $("#production_table").dataTable({
            "sDom": '<"TT"T><"tab"t><"F"fip>',
            "iDisplayLength": -1,
            "sAjaxSource": 'Data.ashx',
            // "sScrollY": y - 217,
            //"sScrollX": "100%",
            "bJQueryUI": true,
            "bDeferRender": true,
            // "bStateSave": true,
            "aaSorting": [[16, 'desc']],
            "sPaginationType": "full_numbers",
            //        "bAutoWidth": false,
            "fnDrawCallback": function(oSettings) {
                addFormat();
                try {
                    $('td').disableTextSelect();
                }
                catch (err) {
                }
            },
            "fnServerData": function(sSource, aoData, fnCallback) {
                $.ajax({
                    dataType: 'json',
                    type: "GET",
                    cache: false,
                    url: sSource,
                    data: aoData,
                    success: fnCallback
                })
            },
            "fnInitComplete": function(oSettings, json) {
                //alert('DataTables has finished its initialisation.');
                //                    addFormat();

                //$('td').disableTextSelect();
            },
            // "bProcessing": true,
            "aoColumns": [
                    { "mDataProp": null, "bSortable": false },
                    { "mDataProp": "serial", "sClass": "serial" },
                    { "mDataProp": "us", "sClass": "us" },
                    { "mDataProp": "type", "sClass": "type" },
                    { "mDataProp": "compartment", "sClass": "compartment" },
                    { "mDataProp": "leg", "sClass": "leg", "bVisible": false },
                    { "mDataProp": "comp", "sClass": "comp", "bVisible": false },
                    { "mDataProp": "patient", "sClass": "patient", "bVisible": false },
                    { "mDataProp": "dob", "sClass": "dob", "bVisible": false },
                    { "mDataProp": "surgeon", "sClass": "surgeon", "bVisible": false },
                    { "mDataProp": "surgery", "sClass": "surgery", "bVisible": false }
//I've truncated this section slightly...
                ]

        });
    updateTable(updateFreq);
});



function updateTable(uF) {
    // Update the table using the fnReloadAjax call method
        timer = setInterval(function() {
            var iStart = oSettings._iDisplayStart;
            oSettings = oTable.fnSettings();
            oTable.fnReloadAjax();
            //oTable.fnDisplayStart(oSettings, iStart, true);
        }, uF);
    }

最佳答案

我早就应该发布这个了。导致这种情况失控的原因是我每 2 秒请求整个数据集(几千行)。

我最终解决这个问题的方法是改变我的数据源,这样在加载时,我会从源中获取所有数据——但之后的任何时候,我都会从一个不同的源中提取,该源只返回更改,因为最后一个请求。它确实减少了发送的数据。结果,内存使用量显着减少,垃圾收集处理任何轻微的攀升也没有问题。

关于javascript - 重复 jQuery 数据表 AJAX 调用的内存管理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8757901/

相关文章:

javascript - 使用 setInterval() 后出现 clearInterval() 未定义错误

javascript - 光滑的轮播同步选择

jquery - jscrollpane 未在 IE 中重新初始化

JQUERY:在 AJAX 生成的结果上使用 sortable() (PHP/MySQL)

javascript - jquery ajax post - json 正在返回但无法正常工作

javascript - 在网站中抓取 Facebook feed

JavaScript 不遵循正确的工作流程

javascript - 用户滚动到页面底部后向上滑动页脚 - 闪烁

javascript - 包含按钮分组行的页面

javascript - 为什么要在 AJAX 删除请求的 url 中用空格替换 - ?