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 и дальше память продолжает расти...
В чём разница? Только в том, что вызывается функция из материнского окна. Вот такая загадка.

Маэстро 16.11.2010 21:22

Цитата:

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

Абстрагируйтесь, пожалуйста, от механизма транспорта данных. Первоочередная проблема в том, что Opera при отправке данных съедает много памяти. Если бы это было 3 Кб - я бы ещё закрыл глаза на это. А тут 300 Кб. У Вас разве нет сайтов с формами? И Вы нигде не используете iframe, а везде используете ajax?
Думаю, что это проблема Оперы. Создание графических микрокопий страниц, чтобы мгновенно их отображать при наведении мышкой на верхушку закладки - это красивенько, прикольно, но не такой ценой. Другими словами, зачем делать микрокопии фреймов в истории по 300 Кб, если тело фрейма содержит код длиной всего 52 байта??

Kolyaj 16.11.2010 21:31

Цитата:

Сообщение от Маэстро
У Вас разве нет сайтов с формами? И Вы нигде не используете iframe

В таком виде не использую.

Маэстро 18.11.2010 12:29

Цитата:

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

Проверил "обычный XMLHttpRequest". Взял по инструкции getXmlHttp() с http://javascript.ru/ajax/intro только добавил метод борьбы с кешированием ответов реквеста Math.random().
Тестирование проводил в трёх броузерах IE6, Mozilla Firefox 3.6.12, Opera 10.63.
Написал скрипт, который шлёт запросы на сервер с частотой 10 раз в секунду (сервер не жалко) и оставил на ночь (с 22:00 до 10:00).
Вот результаты вечер/утро по потребляемой оперативной памяти:
IE: 20М/20М (память осталась на том же уровне)
Fire Fox: 47М/47М (память осталась на том же уровне)
Opera: 36М/380М (!!! - нет слов)

Но это ещё не всё. После закрытия соответствующих вкладок (и отдельного окна IE6) Опера еле-еле шевелилась. Я обнаружил, что общая потребляемая память в компьютере возросла до 2,5 GB! И после полного закрытия Оперы она очистилась до 1,5 GB. Очевидно, что Опера потребляет память не только в собственном EXE-процессе, но и замусоривает какие-то системные ресурсы.
Одним словом вот такая "Опера". Да пусть меня простят пользователи Оперы, но она тупая. Либо её разработчики.
Да и вообще, о чём разговор, если за последний год вышло два десятка её релизов? Это гонка наперегонки с Гуглом? Общеизвестно, что скорострельная разработка приводит к непродуманности функционала и ошибкам. Нельзя так бесцеремонно обращаться с ресурсами Пользователей.
И да пусть меня услышат разработчики.


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