Javascript: нехватка памяти - PullRequest
2 голосов
/ 27 июля 2011

Я работаю над сценарием, который извлекает и затем анализирует большое количество документов XML.Соответствующая часть кода показана ниже.(URL был скрыт для конфиденциальности. Звездочки в коде на самом деле отсутствуют, они используются для справки позже в вопросе)

var xmlhttp = new XMLHttpRequest();
var xmlDoc;
var chunk = parseInt(1, 10);
var subChunk = parseInt(0, 10);
var indvCount = parseInt(0, 10);
var total = parseInt(0, 10);
var max = parseInt(5000, 10);
var end = parseInt(chunk, 10) * parseInt(20, 10);
var start = parseInt(end, 10) - parseInt(19, 10);

function loadXML() {

xmlhttp.abort();
*xmlhttp.open("GET", "URL-GOES-HERE?start=" + start + "&end=" + end, false);
xmlhttp.setRequestHeader('Content-Type', 'text/xml', 'Pragma', 'no-cache');
xmlhttp.send("");
while (xmlhttp.readyState != 4) { }
xmlDoc = xmlhttp.responseXML;
readXML();

}


function readXML() {

while (subChunk < 20) {
    *indvCount = xmlDoc.getElementsByTagName("Value")[subChunk].childNodes[0].nodeValue;
    total = parseInt(total, 10) + parseInt(indvCount, 10);
    subChunk = parseInt(subChunk, 10) + parseInt(1, 10);
}
chunk = parseInt(chunk, 10) + parseInt(1, 10);
subChunk = parseInt(0, 10)
end = parseInt(chunk, 10) * parseInt(20, 10);
start = parseInt(end, 10) - parseInt(19, 10);
if (chunk > max) {
    alert(total);
} else {
    loadXML();
}

}

Когда chunk равноок.5000 или больше, я получаю ошибку Out of Memory.Ошибка обычно относится к одной из строк кода со звездочкой.Используя диспетчер задач Windows, я могу подтвердить, что использование памяти в Internet Explorer остается на уровне 6000 КБ, поэтому я не думаю, что у меня есть утечка памяти.

Кто-нибудь знает способ предотвратить это?

1 Ответ

1 голос
/ 27 июля 2011

Вот ваш readXML, переписанный для устранения бесполезных ошибок.Критика / вопросы после кода:

function readXML() {
    while (subChunk < 20) {
        indvCount = xmlDoc.getElementsByTagName("Value")[subChunk].childNodes[0].nodeValue;
        total = total + parseInt(indvCount, 10);
        subChunk++;
    }
    chunk++;
    subChunk = 0;
    end = chunk * 20;
    start = end - 19;
    if (chunk > max) {
        alert(total);
    } else {
        loadXML();
    }
}
  1. Где вы инициализируете subChunk?При первом вызове readXML subChunk (если это весь ваш код) будет неопределенным.
  2. То же самое для total.Где это определяется / инициализируется?
  3. То же самое для chunk.Где это определено инициализировано?
  4. То же самое для max.Где это определяется как инициализированный?
  5. Обратите внимание, что я исключил все, кроме одного parseint.Если вы не выполняете там все виды сумасшедших преобразований int / string, ЕДИНСТВЕННОЕ место, в котором это строго требовалось бы, это превращать полученную XML-строку в число для вашего total числа.

Хорошо.как насчет переписывания следующим образом ... он все равно будет использовать глобальные переменные (плохо, плохо, плохо), но несколько более правильно и эффективно:

function readXML() {
    var values = xmlDoc.getElementsByTagName("Value");
    for (i = 0; i < values.length; i++) {
       total += parseInt(values[i].childNodes[0].nodeValue);
    }
    chunk++;
    end = chunk * 20;
    start = end - 19;
    if (...) { ... }
}

Ваш код выполняет повторный вызов getElementsByTagName (дорого)), получает доступ к одному значению, затем выбрасывает все остальное.Выполняет другой вызов gEBTN (), получает доступ к другому значению, отбрасывает результаты, yada yada yada.Значительная трата циклов ЦП, памяти и т. Д. С помощью приведенной выше конструкции вы выполняете gEBTN () ONCE , а затем перебираете результаты, вытаскивая все соответствующие узлы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...