Утечка памяти, связанная с запросами jQuery Ajax

У меня есть веб-страница с утечкой памяти как в IE8, так и в Firefox; использование памяти, отображаемое в проводнике Windows, со временем продолжает расти.

На следующей странице запрашивается URL «unplanned.json», который является статическим файлом, который никогда не изменяется (хотя я устанавливаю свойCache-control HTTP-заголовок дляno-cache чтобы убедиться, что запрос Ajax всегда проходит). Когда он получает результаты, он очищает таблицу HTML, перебирает массив json, полученный с сервера, и динамически добавляет строку в таблицу HTML для каждой записи в массиве. Затем он ждет 2 секунды и повторяет этот процесс.

Вот вся веб-страница:

<html> <head>
    <title>Test Page</title>
    <script type="text/javascript"
     src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"></script>
</head> <body>
<script type="text/javascript">
    function kickoff() {
        $.getJSON("unplanned.json", resetTable);
    }
    function resetTable(rows) {
        $("#content tbody").empty();
        for(var i=0; i<rows.length; i++) {
            $("<tr>"
                + "<td>" + rows[i].mpe_name + "</td>"
                + "<td>" + rows[i].bin + "</td>"
                + "<td>" + rows[i].request_time + "</td>"
                + "<td>" + rows[i].filtered_delta + "</td>"
                + "<td>" + rows[i].failed_delta + "</td>"
            + "</tr>").appendTo("#content tbody");
        }
        setTimeout(kickoff, 2000);
    }
    $(kickoff);
</script>
<table id="content" border="1" style="width:100% ; text-align:center">
<thead><tr>
    <th>MPE</th> <th>Bin</th> <th>When</th> <th>Filtered</th> <th>Failed</th>
</tr></thead>
<tbody></tbody>
</table>
</body> </html>

Если это поможет, вот пример json, который я отправляю обратно (именно этот массив содержит тысячи записей вместо одной):

[
    {
        mpe_name: "DBOSS-995",
        request_time: "09/18/2009 11:51:06",
        bin: 4,
        filtered_delta: 1,
        failed_delta: 1
    }
]

РЕДАКТИРОВАТЬ: я принял чрезвычайно полезный ответ Торана, но я чувствую, что я должен опубликовать дополнительный код, так как егоremovefromdom Плагин jQuery имеет некоторые ограничения:

Он удаляет только отдельные элементы. Таким образом, вы не можете дать ему запрос типа `$ (" # content tbody tr ")` и ожидать, что он удалит все указанные вами элементы.Любой элемент, который вы удаляете вместе с ним, должен иметь атрибут `id`. Поэтому, если я хочу удалить свой `tbody`, тогда я должен присвоить` id` моему тегу `tbody`, иначе это выдаст ошибку.Он удаляет сам элемент и всех его потомков, поэтому, если вы просто хотите очистить этот элемент, вам придется заново его создать (или изменить плагин, чтобы он опустел вместо удаления).

Итак, вот моя страница выше, модифицированная для использования плагина Торана. Ради простоты я не применил ни одного из общих рекомендаций по производительностипредложенный Питером, Вот страница, на которой больше нет утечек памяти:

<html>
<head>
    <title>Test Page</title>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"></script>
</head>
<body>
<script type="text/javascript">
<!--
    $.fn.removefromdom = function(s) {
        if (!this) return;

        var el = document.getElementById(this.attr("id"));

        if (!el) return;

        var bin = document.getElementById("IELeakGarbageBin");

        //before deleting el, recursively delete all of its children.
        while (el.childNodes.length > 0) {
            if (!bin) {
                bin = document.createElement("DIV");
                bin.id = "IELeakGarbageBin";
                document.body.appendChild(bin);
            }

            bin.appendChild(el.childNodes[el.childNodes.length - 1]);
            bin.innerHTML = "";
        }

        el.parentNode.removeChild(el);

        if (!bin) {
            bin = document.createElement("DIV");
            bin.id = "IELeakGarbageBin";
            document.body.appendChild(bin);
        }

        bin.appendChild(el);
        bin.innerHTML = "";
    };

    var resets = 0;
    function kickoff() {
        $.getJSON("unplanned.json", resetTable);
    }
    function resetTable(rows) {
        $("#content tbody").removefromdom();
        $("#content").append('<tbody id="id_field_required"></tbody>');
        for(var i=0; i<rows.length; i++) {
            $("#content tbody").append("<tr><td>" + rows[i].mpe_name + "</td>"
                + "<td>" + rows[i].bin + "</td>"
                + "<td>" + rows[i].request_time + "</td>"
                + "<td>" + rows[i].filtered_delta + "</td>"
                + "<td>" + rows[i].failed_delta + "</td></tr>");
        }
        resets++;
        $("#message").html("Content set this many times: " + resets);
        setTimeout(kickoff, 2000);
    }
    $(kickoff);
// -->
</script>
<div id="message" style="color:red"></div>
<table id="content" border="1" style="width:100% ; text-align:center">
<thead><tr>
    <th>MPE</th>
    <th>Bin</th>
    <th>When</th>
    <th>Filtered</th>
    <th>Failed</th>
</tr></thead>
<tbody id="id_field_required"></tbody>
</table>
</body>
</html>

ДОПОЛНИТЕЛЬНОЕ РЕДАКТИРОВАНИЕ: Я оставлю свой вопрос без изменений, хотя стоит отметить, что эта утечка памяти не имеет ничего общего с Ajax. Фактически, следующий код будет точно таким же утечкой памяти и будет легко решаться с помощью Торана.removefromdom Плагин jQuery:

function resetTable() {
    $("#content tbody").empty();
    for(var i=0; i<1000; i++) {
        $("#content tbody").append("<tr><td>" + "DBOSS-095" + "</td>"
            + "<td>" + 4 + "</td>"
            + "<td>" + "09/18/2009 11:51:06" + "</td>"
            + "<td>" + 1 + "</td>"
            + "<td>" + 1 + "</td></tr>");
    }
    setTimeout(resetTable, 2000);
}
$(resetTable);

Ответы на вопрос(3)

Ваш ответ на вопрос