Утечка памяти в IE9 для динамических объектов DOM с атрибутом ID - PullRequest
6 голосов
/ 07 февраля 2012

Я заметил, что присвоение атрибуту ID значения динамически создаваемым объектам DOM приводит к утечке памяти в IE9.Кто-нибудь еще испытывал это и, что более важно, знал о каких-либо обходных решениях?Он не протекает в других браузерах, даже IE6 проходит!

Демонстрация кода утечки:

Он просто непрерывно добавляет и удаляет строки из таблицы и назначает идентификатор каждой строке, которая будет использоваться дляпоиск позже.

Не возникает утечка без "row.id = eid;"

    <html>
    <head>
        <script type="text/javascript">

        function addRow(tbl, index) {
            var row = tbl.insertRow(index);
            var eid = "loongrowid" + count;
            row.id = eid;

            for (var i = 0; i < 9; i++) {
                row.insertCell(i);
            }

            return row;
        }

        function removeTableRow(tbl, index) {
            var row = tbl.rows[index];
            tbl.deleteRow( index );

        }

        var count = 1;

        function fillRow(row){
            row.cells[0].innerHTML = '<input type="checkbox"' + ' checked="checked"' + ' />';
            for (var i = 1; i < 9; i++) { 
                row.cells[i].innerHTML = count + " c";
            }
            ++count;
        }

        var added = false;

        function dostuff() 
        {
            var tbl = document.getElementById("tbl");
            var i;

            if (added)
            {
                for (i = 0; i < 20; ++i)
                {
                    removeTableRow(tbl,1);
                }
            }
            else
            {
                for (i = 0; i < 20; ++i)
                {
                    var row = addRow(tbl, i+1);
                    fillRow(row);
                }
            }

            added = !added;
            setTimeout(dostuff, 1); 
        }
        </script>
    </head>
    <body onload="setTimeout(dostuff, 1)">
    <h1 id="count">TESTING</h1>
    <table id="tbl" style="width:100%;">    
    <tr>
        <th>selected</th>
        <th>date</th>
        <th>time</th>
        <th>place</th>
        <th>device</th>
        <th>text</th>
        <th>state</th>          
        <th>status</th>
        <th>quality</th>
    </tr>
    </table>
    </body>
</html>

Я заметил, что удаление всех ячеек из строки таблицы приводит к уменьшению утечки памяти, поэтому я предполагаю, что IE удерживаетв строку после ее удаления из таблицы.

Я также попытался обойти эту проблему, добавив строки созданной таблицы в объект Javascript, который будет использоваться в качестве хеш-таблицы, вместо того, чтобы полагаться на getElementById (row.id) но это также просочилось по какой-то причине, которую я не вижу.

var hash = [];

    // when creating row
    row.extid = eid; // Note: this by itself causes no leak
hash[eid] = row; 

    // when removing row
delete hash[row.extid]; 

Ответы [ 2 ]

2 голосов
/ 13 февраля 2012

Я нашел подходящее решение в моем случае, заметив, что перезагрузка включенной тестовой страницы после того, как она некоторое время «работала», приводила к тому, что использование памяти временно оставалось постоянным (относительно времени, которое она проработала до перезагрузки). После этого он снова начал расти.

Итак, похоже, что да, IE не удаляет ресурсы, используемые элементами ID: d полностью после удаления элемента, но он, очевидно, будет повторно использовать эти ресурсы, если тот же ID будет добавлен на страницу снова.

Значит, просто убедитесь, что добавляемые и удаляемые идентификаторы являются частью ограниченного набора, а не неограниченного. На тестовой странице используются строго увеличивающиеся целочисленные идентификаторы, а в моем исходном случае проблемы использовались идентичные идентификаторы порядкового номера. К счастью, в обоих случаях их довольно легко зафиксировать на ограниченном диапазоне.

Для кода теста выше:

++ рассчитывать; if (count> 1000) count = 0;

0 голосов
/ 09 февраля 2012

В мои дни Java Swing (да, да, я стар), у JVM была несколько похожая проблема. При этом сборщик мусора не сможет очистить объекты Swing, которые были вложены в другие объекты Swing, что приведет к утечке памяти.

Раньше я обходил это, явно устанавливая для каждого объекта Swing значение NULL, поскольку они больше не нужны.

В случае глубоко вложенных объектов (т. Е. Таблиц Swing, содержащих другие объекты Swing), я написал рекурсивный метод, который может использоваться всеми моими классами Swing, который будет проходить через любой объект Swing, обнуляя каждый объект. найдено внутри.

Было неприятно, что мне пришлось пройти через все эти дополнительные усилия, чтобы обойти ошибку в сборщике мусора JVM, но она работала прекрасно. Как только я это установил, утечки памяти исчезли.

Возможно, стоит попробовать что-то подобное с IE9. Преобразование объектов DOM в NULL, поскольку они больше не нужны, может решить эту проблему за вас. И остальные из нас ...: -)

...