Javascript-форум (https://javascript.ru/forum/)
-   Opera, Safari и др. (https://javascript.ru/forum/css-html-browser/)
-   -   Сумасшедшая утечка памяти в Opera при использовании javascript в IFRAME (https://javascript.ru/forum/css-html-browser/13124-sumasshedshaya-utechka-pamyati-v-opera-pri-ispolzovanii-javascript-v-iframe.html)

Маэстро 16.11.2010 14:13

Сумасшедшая утечка памяти в Opera при использовании javascript в IFRAME
 
Обнаружил утечку памяти в броузере Opera при элементарно-простых операциях. Память съедается в размере 500 MByte в час... Исследования проводились в Opera 10.63. В Google Crome, Fire Fox, IE6, IE8 эффект не наблюдается. Что делать?
Пример:
первый скрипт:
http://gigalit.com.ua/test/test9.htm
-на странице форма отправки POST и фрейм, принимающий ответ от сервера:
<script type="text/javascript">
function f2()
{
// ничего не делает
}
</script>


<iframe id="data" name="data"></iframe>
<form method="POST" action="test8.htm"  target="data">
<input type=text name="x">
<input type=submit value="OK">
</form>


второй скрипт:
http://gigalit.com.ua/test/test8.htm
<script type="text/javascript">
parent.f2();
</script>

При нажатии на кнопку отправки память съедается на 300KB, через 3-4 клика уже +1 MByte...
Обратите внимание, что вызываемая у parent-окна функция f2() не имеет никаких переменных, не создаёт никаких объектов, т.е. ничего не делает.
Кто может подсказать? Может, после вызова функции что-то как-то надо искусственно подчищать?

Gvozd 16.11.2010 15:06

[telepatemode]
да, у вас наверно включено кеширование страниц.
как итог, на каждую загруженную страницу сохраняется кеш, и вы спокойно можете ходить внутри фрейма по всей его истории
попробуйте удалять фрейм каждый раз, когда уже не нужен его старый экземпляр, и создавать на его месте новый фрейм
[/telepatemode]

Kolyaj 16.11.2010 15:12

Опера любит сохранять страницы в памяти для моментального перехода по кнопке "Назад".

Маэстро 16.11.2010 15:24

Цитата:

Сообщение от Gvozd (Сообщение 79487)
да, у вас наверно включено кеширование страниц.

О кешировании я подумал в первую очередь и проверил. Всё поотключал. Кстати, в Опере в настройках есть опция "Запоминать посещённые адреса для истории и автозаполнения" и по-умолчанию стоит значение 500! И его отключил - ситуация осталась прежняя. Но суть не в этом. Я ведь не буду рекомендовать всем посетителям сайта отключать кэширование страниц, если они работают в Опере?!! (с грозным предупреждением, что через час произойдёт переполнение памяти компьютера...


Цитата:

Сообщение от Gvozd (Сообщение 79487)
попробуйте удалять фрейм каждый раз, когда уже не нужен его старый экземпляр, и создавать на его месте новый фрейм

Удалять фрейм не могу, т.к. на него ссылаются другие формы. Т.е. он должен "висеть" постоянно (чтобы принимать ответы с сервера).
Кроме этого, могу сообщить Вам, что в Fire Fox проблема с удалением фреймов. Если коротко, то он их не удаляет. Точнее, "делает вид", что удаляет, но оставляет копии объектов в памяти. Поэтому, создав фрейм с идентификатором/именем test, удалив его и создав новый с тем же именем test вы получите ссылку на старый объект.

Kolyaj 16.11.2010 15:28

А зачем вам фрейм вообще? Чем обычный XMLHttpRequest не устраивает?

Gvozd 16.11.2010 15:30

попробуйте подчищать историю за фреймом.
history.back() для фрейма перед отправкой формы.
таким образом в его истории не будет накапливаться страниц, и полагаю память также не будет накапливаться.
сам не проверял

Маэстро 16.11.2010 15:32

Цитата:

Сообщение от Kolyaj (Сообщение 79489)
Опера любит сохранять страницы в памяти для моментального перехода по кнопке "Назад".

Для перехода по кнопке "Назад" надо сохранять ссылки (или содержимое) страниц сайтов, либо содержимое фреймов, когда оно получено методом изменения URL фрейма, например так:
top.myframe.location.href = 'newpage.htm';

или так:
top.myframe.location.replace('newpage.htm');

Причём насколько я помню, при replace() броузер НЕ должен запоминать и делать возврат по кнопке.

Но для фреймов, данные в которые загружаются не изменением его src/location, а с помощью указания свойства target формы - запоминание всех принятых данных в истории броузера - абсурд.

Маэстро 16.11.2010 15:39

Цитата:

Сообщение от Kolyaj (Сообщение 79492)
А зачем вам фрейм вообще? Чем обычный XMLHttpRequest не устраивает?

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

Kolyaj 16.11.2010 15:43

Ну почему же, мы можем прийти к решению вашей первоочередной проблемы, вместо решения проблемы-следствия.

Маэстро 16.11.2010 21:15

Цитата:

Сообщение от Gvozd (Сообщение 79493)
попробуйте ... history.back() для фрейма перед отправкой формы...
сам не проверял

Трудно представить, что произойдёт в системе, если сделать history.back(). По сути это то же самое, что повторно загрузить в фрейм то, что было загружено шаг назад. Предположим, в фрейм приехала javascript-команда (функция), которая на главной странице открыла окно. Тогда history.back() откроет дубликат такого окна. А зачем?
Но я поработал с history и выявил интересные и странные вещи.
Добавил на главную страницу две кнопки:
<input type=button value="history.back" onclick=history.back();>
<input type=button value="history.length" onclick=alert(history.length);>

и сделал две разновидности скрипта, загружаемого во фрейм:
<script type="text/javascript">parent.f2();</script>

и
<script type="text/javascript">function f1(){}</script>

Первый вызывает функцию из parent-окна, второй вызывает локальную функцию, расположенную внутри фрейма.
Мои наблюдения: (может кто-то и знает, а для меня было новостью, что) при отправке данных с формы history.length доходит до значения 50 и останавливается. То есть, Opera запоминает историю в 50 страниц (на каждой вкладке). Где это число 50 в настройках??
А теперь главное:
При вызове во фрейм второго скрипта history.length вырастает до числа 50, Opera съедает памяти около 10 Mbyte и дальше потребление памяти не увеличивается!
При вызове во фрейм первого скрипта history.length также вырастает до числа 50 и дальше память продолжает расти...
В чём разница? Только в том, что вызывается функция из материнского окна. Вот такая загадка.


Часовой пояс GMT +3, время: 01:43.