Я провел весь уик-энд, чтобы выяснить проблему роста памяти в своем веб-приложении, написанном в Dojo.
Веб-приложение будет запускаться навсегда, поэтому перезапуск браузера не планируется.
Приложение обновляет динамические данные с сервера (без перекрестного домена) на регулярной основе; каждые 5 секунд выполняется вызов AJAX для извлечения новых данных как JSON.
Позволяя приложению работать в течение нескольких часов, я наблюдал постоянный рост в памяти браузера (как на последних Chrome, так и на Firefox, как на последних Windows, так и на Mac OS X).
Сначала я думал, что Dojo вызывает такое поведение. И действительно, переключившись на собственную реализацию с объектом XMLHttpRequest, я мог резко сократить объем памяти, но он все еще существует. С каждым запросом AJAX память растет немного (около 4-8 КБ).
Что я уже пробовал:
У меня есть...
- ... пытался использовать другие фреймворки, такие как jQuery, YUI и т.д. - no effect
- ... перешел на использование собственного объекта XMLHttpRequest - помог много, но не полностью
- ... деактивированное манипулирование DOM после получения данных - без эффекта
- ... сбросил `xhr`, установив "null" и удалив его после каждой итерации - no effect
- ... сбросил обработчик onreadystatechange до нулевого или пустого метода после каждой итерации - no effect
- ... повторно использовал объект `xhr` и обработчик` onreadystatechange`, поскольку он всегда один и тот же - без эффекта
Итак, даже если я ничего не делаю (как описано в первой ссылке StackOverflow ниже) с загруженными данными, использование памяти увеличивается:
Что я уже читал:
- Утечка памяти с XMLHttpRequest и setInterval
- Автоматическая утечка памяти обновления веб-страницы с использованием XMLHttpRequest
- Утечка памяти при завершенной функции XMLHttpRequest
- http://forum.jquery.com/topic/memory-leaks-with-ajax-calls
- и многое другое...
Мой тестовый HTML-код:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Native XHR Async</title>
</head>
<body>
<script>
var update = document.createElement("div");
document.body.appendChild(update);
var timeout = null;
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = onReadyState;
function loadData()
{
xhr.open("GET","memory-leak.json?" + new Date().getTime());
xhr.send(null);
}
function onReadyState()
{
if (this.readyState === 4)
{
if( this.status === 200 )
{
update.innerHTML = "";
update.innerHTML = this.responseText;
}
if( timeout !== null )
{
clearTimeout(timeout);
delete timeout;
}
timeout = setTimeout(loadData, 1000);
}
}
loadData();
</script>
</body>
</html>
И мой тестовый JSON (в том же каталоге):
{
"errorstatus":"Okay",
"B0":{"P":"0 Watt"},
"E0":{"P":"28 Watt"},
"Z0":{"P":"28 Watt"},
"S0":{"P":"0 Watt","SOC":"74%"},
"Z1":{"P":"0 Watt"},
"R0":0,
"R1":0,
"R2":0,
"date":"29.09.2012 09:23:19",
"Version":"Sep 28 2012-15.22"
}
У меня нет объяснений по этой проблеме, поэтому любая помощь очень ценится. Если вам нужна дополнительная информация об этом, пожалуйста, не стесняйтесь спрашивать меня.