Утечка памяти IE9 HTA с обновлением Javascript таблицы HTML

Доброе утро,

Я использую HTA в своей компании, поскольку они быстрые, грязные и простые для понимания для всех, кому нужно вносить изменения, когда это необходимо (и я предпочитаю NP++ любой другой среде кода, которую я использовал до сих пор, но без компилятора).

Я сделал HTA (на основе IE9, но протестирован в IE11, так как они являются стандартом компании) для отображения некоторых внутренних данных в другом отделе, эти данные будут время от времени обновляться в течение дня по мере необходимости. Эти данные создаются в локальном текстовом файле и импортируются с помощью ActiveXObject XMLHttp или XMLHttpRequest, где это возможно. Проблема в том, что когда таблица обновляется, она каждый раз теряет немного памяти.

Первоначально я думал, что утечка произошла из-за XML-запроса, но я привязал его к моменту фактического обновления таблицы.

Код выглядит следующим образом:

// Create the object arrays
var vData={}, vObject={}, vMethod={}, vEvent={};

// Function to update the table
vMethod.updateTable = function() {
    vData.fileName = 'out_comm/Data.txt';
    vData.fileText = '';
    try {
        vObject.rawFile = new XMLHttpRequest();
        vObject.rawFile.open('GET', vData.fileName, false);
        vObject.rawFile.onreadystatechange = function() {
            if (vObject.rawFile.readyState === 4) {
                if (vObject.rawFile.status === 200 || vObject.rawFile.status === 0) {
                    vData.fileText = vObject.rawFile.responseText;
                }
            }
        };
        vObject.rawFile.send();
    } catch (e) {
        try {
            vObject.rawFile = new ActiveXObject('Microsoft.XMLHTTP');
            vObject.rawFile.open('GET', vData.fileName, false);
            vObject.rawFile.onreadystatechange = function() {
                if (vObject.rawFile.readyState === 4) {
                    if (vObject.rawFile.status === 200 || vObject.rawFile.status === 0) {
                        vData.fileText = vObject.rawFile.responseText;
                    }
                }
            };
            vObject.rawFile.send();
        } catch (e) {
            alert('Error: ' + e.getMessage());
        }
    }
    delete vObject.rawFile;
    vData.tableHTML = '';
    vData.BlockCount = 0;
    vData.BlockNum = 1;
    vData.BlockLetter = 'A';
    vData.rowEven = true;
    vData.fileTextSplit = vData.fileText.split('\n');
    vData.tableHTML = '<table id="dataTable" cellspacing="0"><thead><tr><th></th><th></th><th></th><th></th>';
    vData.tableHTML = vData.tableHTML + '<th>5</th><th>4</th><th>3</th><th>2</th><th>1</th>';
    vData.tableHTML = vData.tableHTML + '<th>5</th><th>4</th><th>3</th><th>2</th><th>1</th>';
    vData.tableHTML = vData.tableHTML + '<th>5</th><th>4</th><th>3</th><th>2</th><th>1</th>';
    vData.tableHTML = vData.tableHTML + '<th>5</th><th>4</th><th>3</th><th>2</th><th>1</th>';
    vData.tableHTML = vData.tableHTML + '</tr></thead><tbody>';
    for (vData.arrayCount = 0;vData.arrayCount < vData.fileTextSplit.length; vData.arrayCount++) {
        if (vData.fileTextSplit[vData.arrayCount] !== '') {
            vData.fileTextLineSplit = vData.fileTextSplit[vData.arrayCount].split(',');
            if (vData.BlockCount == 4) {
                vData.BlockCount = 0;
                if (vData.rowEven) {
                    vData.rowEven = false;
                } else {
                    vData.rowEven = true;
                }
            }
            if (vData.rowEven) {
                vData.tableHTML = vData.tableHTML + '<tr id="item_' + vData.arrayCount + '" class="even">';
            } else {
                vData.tableHTML = vData.tableHTML + '<tr id="item_' + vData.arrayCount + '">';
            }
            vData.BlockCount ++;
            vData.tableHTML = vData.tableHTML + '<td>' + vData.fileTextLineSplit[0].substring(6, 8) + '/' + vData.fileTextLineSplit[0].substring(4, 6) + '</td>';
            vData.tableHTML = vData.tableHTML + '<td>1A</td>';
            vData.tableHTML = vData.tableHTML + '<td>01</td>';
            vData.tableHTML = vData.tableHTML + '<td>' + vData.fileTextLineSplit[1] + '</td>';
            vData.tableHTML = vData.tableHTML + '<td class="split">' + vData.fileTextLineSplit[2] + '</td>';
            vData.tableHTML = vData.tableHTML + '<td>' + vData.fileTextLineSplit[3] + '</td>';
            vData.tableHTML = vData.tableHTML + '<td>' + vData.fileTextLineSplit[4] + '</td>';
            vData.tableHTML = vData.tableHTML + '<td>' + vData.fileTextLineSplit[5] + '</td>';
            vData.tableHTML = vData.tableHTML + '<td>' + vData.fileTextLineSplit[6] + '</td>';
            vData.tableHTML = vData.tableHTML + '<td>' + vData.fileTextLineSplit[7] + '</td>';
            vData.tableHTML = vData.tableHTML + '<td>' + vData.fileTextLineSplit[8] + '</td>';
            vData.tableHTML = vData.tableHTML + '<td>' + vData.fileTextLineSplit[9] + '</td>';
            vData.tableHTML = vData.tableHTML + '<td>' + vData.fileTextLineSplit[10] + '</td>';
            vData.tableHTML = vData.tableHTML + '<td>' + vData.fileTextLineSplit[11] + '</td>';
            vData.tableHTML = vData.tableHTML + '<td class="split">&pound;0</td>';
            vData.tableHTML = vData.tableHTML + '<td>&pound;0</td>';
            vData.tableHTML = vData.tableHTML + '<td>&pound;0</td>';
            vData.tableHTML = vData.tableHTML + '<td>&pound;0</td>';
            vData.tableHTML = vData.tableHTML + '<td>&pound;0</td>';
            vData.tableHTML = vData.tableHTML + '<td>&pound;0</td>';
            vData.tableHTML = vData.tableHTML + '<td>&pound;0</td>';
            vData.tableHTML = vData.tableHTML + '<td>&pound;0</td>';
            vData.tableHTML = vData.tableHTML + '<td>&pound;0</td>';
            vData.tableHTML = vData.tableHTML + '<td>&pound;0</td>';
            vData.tableHTML = vData.tableHTML + '</tr>';
        }
    }
    vData.tableHTML = vData.tableHTML + '</tbody></table>';
    document.getElementById("dataTableDiv").innerHTML = '';
    document.getElementById("dataTableDiv").innerHTML = vData.tableHTML;

    delete vData.fileName;
    delete vData.tableHTML;
    delete vData.fileTextLineSplit;
    delete vData.rowEven;
    delete vData.fileTextSplit;
    delete vData.fileText;
    delete vData.BlockCount;
    delete vData.BlockNum;
    delete vData.BlockLetter;
    delete vObject.rawFile;
    delete vData.arrayCount;
};

Я пытался использовать чистый javascript, jquery и их комбинацию, чтобы очистить таблицу и повторно импортировать данные без сокращения использования памяти.

Я все еще учусь и поэтому не особенно разбираюсь в Java, поэтому я могу упустить что-то простое. Я видел много форумов (старых, но актуальных), в которых говорится, что таблицы в IE всегда были немного сомнительными, но ничего нового и никаких реальных решений. Возможно, причиной проблемы является среда HTA, но у меня нет возможности доказать это, так как все работает в автономном режиме, поэтому я не могу выполнить локальный XML в IE из-за ограничений безопасности.

Любая помощь будет принята с благодарностью

Изменить

Просто быстрое редактирование; Я также пытался использовать функцию JQuerys .remove() и .empty(), но безрезультатно. Причина, по которой я устанавливаю переменные в массивы объектов (я думаю, что эта терминология верна), заключается в том, что я могу использовать функцию удаления, поскольку я предполагал, что это были переменные, занимающие память.


person AranDG    schedule 05.11.2015    source источник
comment
Я не удивлюсь, если утечка памяти произойдет в document.getElementById("dataTableDiv").innerHTML = vData.tableHTML; из-за того, как IE отрисовывает, и проблем с производительностью, которые я наблюдал в прошлом при рендеринге больших объемов динамических данных.   -  person user692942    schedule 05.11.2015
comment
Хотя вы используете IE 11, вам может показаться интересным: Утечка памяти происходит, когда свойство InnerHTML элемента неоднократно обновляется в Internet Explorer 8. Интересно, какой двигатель использует mshta.exe?   -  person user692942    schedule 05.11.2015
comment
Также может показаться интересным - .append VS .html производительность VS .innerHTML один из ответы напрямую ссылаются на исходный код JQuery для функции html(), в которой есть комментарий, относящийся к innerHTML, по строкам // Remove element nodes and prevent memory leaks.   -  person user692942    schedule 05.11.2015
comment
Что касается производительности, вы можете обнаружить, что этот интересующий ответ использует массив для ускорения процесса.   -  person user692942    schedule 05.11.2015
comment
@Lankymart Да, именно здесь возникает утечка памяти, как уже говорилось, я ранее предполагал, что это было в ActiveXObject, но, к сожалению, не так, как это было бы быстрым решением. Я считаю, что mshta.exe должен использовать любой установленный в данный момент движок, я пробовал его на машинах с IE9 и IE11, и оба возвращают одну и ту же проблему. И да, хотя метод append() работает быстрее, к сожалению, это не повлияло на мою проблему с утечкой памяти, но я буду использовать этот метод интеграции в будущем. Спасибо за ваши предложения до сих пор, хотя   -  person AranDG    schedule 05.11.2015
comment
Возможно, это не так, вам может потребоваться использовать X-UA-Compatible, чтобы настроить приложение HTA на использование режима Edge, по умолчанию HTA используют режим совместимости в соответствии с этой ответ от Как получить поддержку стандартов IE9 для диалогов, открытых HTA?. Также что касается append(), это не быстрее, а медленнее, чем innerHTML(), если вы выходите из тестов в этом ответе SO.   -  person user692942    schedule 05.11.2015
comment
к сожалению, я уже использую этот тег при создании HTA, так как сталкивался с некоторыми проблемами системы сетки CSS3 без него. Тег для справки ‹мета http-equiv=x-ua-совместимый контент=ie=edge/›   -  person AranDG    schedule 05.11.2015
comment
Вы проверили, что delete действительно делает то, что вы ожидаете? Из документов MSDNЕсли результатом выражения является объект, свойство, указанное в выражении, существует, и объект не позволит его удалить, возвращается false. Во всех остальных случаях возвращается true.. Поскольку вы не проверяете возвращаемое значение delete, знаете ли вы, что они на самом деле удаляются?   -  person user692942    schedule 05.11.2015
comment
Да, я изначально пошел по этому пути. После удаления переменная возвращается как неопределенная. Я даже пробовал добавлять = '' и = null перед каждым удалением, но использование памяти не изменилось.   -  person AranDG    schedule 05.11.2015
comment
Ну это я без идей. Если это неотъемлемая проблема с утечкой памяти свойства innerHTML, я не уверен, как вы ее исправите.   -  person user692942    schedule 05.11.2015
comment
Да, та же лодка, к сожалению. Я, вероятно, смогу обойти это, используя выровненные div в сетке, это просто будет грязный код, вот и все. Спасибо за вашу помощь в этом, по крайней мере, я знаю, что это не что-то простое, что я просто упустил из виду.   -  person AranDG    schedule 05.11.2015