Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737
Форумы портала PHP.SU :: Утечки памяти JS

 PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи


 Страниц (2): [1] 2 »   

> Описание: Утечки памяти JS
MAXUS
Отправлено: 03 Февраля, 2014 - 16:34:20
Post Id


Посетитель


Покинул форум
Сообщений всего: 329
Дата рег-ции: Апр. 2011  


Помог: 7 раз(а)




Доброго времени суток!

Подскажите, плз, светлые головы! Насколько актуален в 2014 году вопрос утечек памяти в JS? Стал изучать проблему. Пока достаточно поверхностно, но вообще уже складывается ощущение, что код на js - это обильно засаженное минное поле. Чихнул - и потеклоУлыбка
С другой стороны практически все статьи об утечках памяти датируются где-то не позднее 2008 года. Вот я и задумался, а насколько актуальна тема? И если актуальна, то не поделится ли уважаемое сообсчество свежими ссылками где почитать о современном состоянии проблемы?
Заранее благодарен, и прочая, и прочаяУлыбка
 
 Top
Мелкий Супермодератор
Отправлено: 03 Февраля, 2014 - 17:51:46
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 618 раз(а)




Очень даже актуален. Я не слежу за фронтендом и то вижу материалы по этой теме.
Например, о яндекс.почте: http://habrahabr[dot]ru/company/yandex/blog/195198/


-----
PostgreSQL DBA
 
 Top
nerv
Отправлено: 03 Февраля, 2014 - 20:31:43
Post Id



Посетитель


Покинул форум
Сообщений всего: 407
Дата рег-ции: Февр. 2013  
Откуда: Россия


Помог: 9 раз(а)




еще ссылка
http://learn[dot]javascript[dot]ru/memory-leaks

на данный момент одно из главных правил, кот. осталось:
- рвать ссылки на удаленные ноды (dom)

Еще я руководствуюсь следующей логикой: поскольку в js очистка памяти происходит автоматически (сборщиком мусора), надо ему помогать.

Пример простого деструктора для любого объекта:
CODE (javascript):
скопировать код в буфер обмена
  1. Object.prototype.destroy = function() {
  2.     var props = Object.keys(this);
  3.     for(var key in props) {
  4.         delete this[props[key]];
  5.     }
  6. };

В большинстве случаев этого будет достаточно, иногда избыточно) Чтобы работало, надо правильно писать код Улыбка

(Отредактировано автором: 03 Февраля, 2014 - 20:45:15)



-----
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук
 
 Top
OrmaJever
Отправлено: 03 Февраля, 2014 - 20:44:10
Post Id



Активный участник


Покинул форум
Сообщений всего: 7540
Дата рег-ции: Янв. 2010  
Откуда: Чернигов


Помог: 299 раз(а)




Мелкий пишет:
Очень даже актуален.

Утечки памяти в js? Мир больше никогда не станет прежним А?!


-----
Если вы хотя бы 3-4 раза не решите всё выкинуть и начать заново - вы явно что-то делаете не так.
 
 Top
MAXUS
Отправлено: 04 Февраля, 2014 - 06:03:11
Post Id


Посетитель


Покинул форум
Сообщений всего: 329
Дата рег-ции: Апр. 2011  


Помог: 7 раз(а)




Мелкий пишет:
Очень даже актуален. Я не слежу за фронтендом и то вижу материалы по этой теме.
Например, о яндекс.почте: http://habrahabr.ru/company/yandex/blog/195198/


Спасибо. Читал.
(Добавление)
nerv пишет:
еще ссылка
http://learn[dot]javascript[dot]ru/memory-leaks

Это тоже читал. Но это старое. Вопрос насколько актуально.
(Добавление)
Попробую вопрос конкретизировать.

CODE (javascript):
скопировать код в буфер обмена
  1. var a=new function(){
  2.  
  3. };
  4.  
  5. (function() {
  6.  
  7.                 function close(){
  8.                         this.node.parentNode.removeChild(this.node);
  9.                         delete(stack[this.settings.id]);
  10.                 }
  11.                 var stack={},
  12.                 init={
  13.                         "new":function(settings){
  14.                                 if(!settings||!settings.id) return false;
  15.                                 var div=document.createElement("div");
  16.                                 div.id=settings.id;
  17.                                 div.style.cssText="width: 100px; height: 100px; background: red;";
  18.                                 stack[settings.id]={
  19.                                         "settings":settings,
  20.                                         "node": div,
  21.                                         "close":close
  22.                                 };
  23.                                 document.body.appendChild(div);
  24.                         },
  25.                         "getStack":function(){
  26.                                 console.log(stack);
  27.                         }
  28.                 }
  29.                 function fn(id){
  30.                         if(id){
  31.                                 if(stack[id]) return stack[id];
  32.                                 else return false;
  33.                         }
  34.                         else return init;
  35.                 }
  36.                
  37.                 a.b=fn;
  38.                
  39. })();
  40.  
  41. window.onload=function(){
  42.         for(var i=0; i<100; i++){
  43.                 a.b().new({"id":"newDiv"+i});
  44.                 a.b("newDiv"+i).close();
  45.         }
  46.         console.log("Ready");
  47. }

Вот в этой ситуации будут утечки? Кто может опытным взглядом оценить?
(Добавление)
OrmaJever пишет:
Утечки памяти в js? Мир больше никогда не станет прежним


А чем вызвана ирония? Улыбка
(Добавление)
Относительно примера.

Если глянуть на эту функцию:
CODE (javascript):
скопировать код в буфер обмена
  1.  
  2. function close(){
  3.                         this.node.parentNode.removeChild(this.node);
  4.                         delete(stack[this.settings.id]);
  5. }


Я понимаю, что если вот эту строчку убрать

CODE (javascript):
скопировать код в буфер обмена
  1. delete(stack[this.settings.id]);


то ноды зависнут и не удалятся. Верно, ведь рассуждаю? А другие подводные камни есть в примере?
(Добавление)
nerv пишет:
В большинстве случаев этого будет достаточно, иногда избыточно) Чтобы работало, надо правильно писать код


Слушай, а поясни смысл этой конструкции. Т.е. я так понимаю, что ты расширяешь стандартный тип Object, добавляя туда функцию destroy, которая собирает все ключи объекта и удаляет их содержимое (ну и сами ключи тоже). И, насколько я понимаю, эту функцию надо вызывать вручную?
Просто ключи все равно собираются только с первого уровня, а если внутри этого объекта есть еще объекты, то с ними что будет? Тоже вручную? Или расчет на то, что они убьются при очистке первого уровня? В таком случае простым delete(нужный объект) это не решается?

(Отредактировано автором: 04 Февраля, 2014 - 06:32:25)

 
 Top
IllusionMH
Отправлено: 04 Февраля, 2014 - 10:33:34
Post Id



Активный участник


Покинул форум
Сообщений всего: 4254
Дата рег-ции: Февр. 2011  
Откуда: .kh.ua


Помог: 242 раз(а)




MAXUS, запускаете свой код на догое время и смотрите на состояние памяти. На глаз так никто отлавливать не будет.
 
 Top
OrmaJever
Отправлено: 04 Февраля, 2014 - 12:10:26
Post Id



Активный участник


Покинул форум
Сообщений всего: 7540
Дата рег-ции: Янв. 2010  
Откуда: Чернигов


Помог: 299 раз(а)




MAXUS пишет:
А чем вызвана ирония?

Интерпретатор должен следить за всем, и по-моему утечки памяти возможны только в компилируемых языках.


-----
Если вы хотя бы 3-4 раза не решите всё выкинуть и начать заново - вы явно что-то делаете не так.
 
 Top
MAXUS
Отправлено: 04 Февраля, 2014 - 12:37:37
Post Id


Посетитель


Покинул форум
Сообщений всего: 329
Дата рег-ции: Апр. 2011  


Помог: 7 раз(а)




IllusionMH пишет:
MAXUS, запускаете свой код на догое время и смотрите на состояние памяти. На глаз так никто отлавливать не будет.


Понятно... Я думал шаблоны утечек кто-нибудь выкупит сходу.
(Добавление)
OrmaJever пишет:
MAXUS пишет:
А чем вызвана ирония?

Интерпретатор должен следить за всем, и по-моему утечки памяти возможны только в компилируемых языках.


А... Ну, тут все равно что говорить "чайник вскипел". В смысле, вскипает не чайник, а вода в немУлыбка Т.е. утечки в интерпретаторах, конечно, имеются в видуУлыбка
 
 Top
IllusionMH
Отправлено: 04 Февраля, 2014 - 12:46:23
Post Id



Активный участник


Покинул форум
Сообщений всего: 4254
Дата рег-ции: Февр. 2011  
Откуда: .kh.ua


Помог: 242 раз(а)




MAXUS, всем безумно интересно изучать простыню кода на наличие возможных утечек.
Если не ошибаюсь, еще от движка может зависеть, так что точно не скажешь.
 
 Top
OrmaJever
Отправлено: 04 Февраля, 2014 - 12:57:19
Post Id



Активный участник


Покинул форум
Сообщений всего: 7540
Дата рег-ции: Янв. 2010  
Откуда: Чернигов


Помог: 299 раз(а)




MAXUS пишет:
Т.е. утечки в интерпретаторах, конечно, имеются в виду

Но тогда как это относится к коду, ну в смысле это грубо говоря баг в браузере, js кодом это не как не исправить, и смысл это обсуждать)))


-----
Если вы хотя бы 3-4 раза не решите всё выкинуть и начать заново - вы явно что-то делаете не так.
 
 Top
caballero
Отправлено: 04 Февраля, 2014 - 13:21:05
Post Id


Активный участник


Покинул форум
Сообщений всего: 5998
Дата рег-ции: Сент. 2011  
Откуда: Харьков


Помог: 126 раз(а)




разные функции и языковые конструкци по разному теряют память
иногда можно уменьшить если переписать код по другому


-----
Бесплатная система складского учета с открытым кодом https://zippy[dot]com[dot]ua/zstore
 
 Top
MAXUS
Отправлено: 05 Февраля, 2014 - 21:21:11
Post Id


Посетитель


Покинул форум
Сообщений всего: 329
Дата рег-ции: Апр. 2011  


Помог: 7 раз(а)




OrmaJever пишет:
MAXUS пишет:
Т.е. утечки в интерпретаторах, конечно, имеются в виду

Но тогда как это относится к коду, ну в смысле это грубо говоря баг в браузере, js кодом это не как не исправить, и смысл это обсуждать)))


А вот это совершенно не факт. Можно замыканиями стока утечек наделать. И браузер будет не при чем.
 
 Top
OrmaJever
Отправлено: 05 Февраля, 2014 - 21:30:28
Post Id



Активный участник


Покинул форум
Сообщений всего: 7540
Дата рег-ции: Янв. 2010  
Откуда: Чернигов


Помог: 299 раз(а)




MAXUS пишет:
Можно замыканиями стока утечек наделать

но ведь при выходе с функции всё должно очищаться, как по другому?


-----
Если вы хотя бы 3-4 раза не решите всё выкинуть и начать заново - вы явно что-то делаете не так.
 
 Top
nerv
Отправлено: 05 Февраля, 2014 - 22:50:45
Post Id



Посетитель


Покинул форум
Сообщений всего: 407
Дата рег-ции: Февр. 2013  
Откуда: Россия


Помог: 9 раз(а)




MAXUS пишет:
И, насколько я понимаю, эту функцию надо вызывать вручную?

да

MAXUS пишет:
В таком случае простым delete(нужный объект) это не решается?

решается. Разница только в том, что когда ссылок много проще так.

А еще правильней создавать объекты (экземпляры класса) через собственные конструкторы и прописывать деструкторы в них

(Отредактировано автором: 05 Февраля, 2014 - 22:53:28)



-----
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук
 
 Top
MAXUS
Отправлено: 06 Февраля, 2014 - 10:50:08
Post Id


Посетитель


Покинул форум
Сообщений всего: 329
Дата рег-ции: Апр. 2011  


Помог: 7 раз(а)




OrmaJever пишет:
MAXUS пишет:
Можно замыканиями стока утечек наделать

но ведь при выходе с функции всё должно очищаться, как по другому?


CODE (javascript):
скопировать код в буфер обмена
  1.  
  2. function leak(){
  3.         var stack={};
  4.         var node=document.createElement("div");
  5.         for(var i=0;i<10;i++){
  6.                 stack[i]=document.body.appendChild(node.cloneNode());
  7.                 stack[i].id="id"+i;
  8.                 stack[i].parentNode.removeChild(stack[i]);
  9.         }
  10.         showStack=function(){
  11.                 console.log(stack);
  12.         }
  13. }
  14.  
  15. window.onload=function(){
  16.         leak();
  17. }
  18.  


Запусти этот код. Потом в консоли вызови showStack(), увидишь, что ноды не удалились, поскольку присутствуют в стэке. Они просто открепились от документа, но остались в памяти. А вот если убрать функцию showStack(), то ноды и объект stack удалятся, что можно проверить в GC profile, сняв heap snapshot и во view "containment" проверить detached nodes... И это не вина браузера, а пример не верно составленного кода.

(Добавление)
nerv пишет:
MAXUS пишет:
В таком случае простым delete(нужный объект) это не решается?

решается. Разница только в том, что когда ссылок много проще так.

А еще правильней создавать объекты (экземпляры класса) через собственные конструкторы и прописывать деструкторы в них


Дак вот я и не пойму. Есть, например объект x. В твоем примере мы вызываем x.destroy() и запускаем функцию, которая убивает все ключи объекта, но не сам объект.

Во-первых, чем запись delete(x) сложнее, чем x.destroy()?
Во-вторых, объект-то у тебя не удаляется, а просто очищается. Если нужно очистить объект, то вместо delete(x) используем x={}, что быстрее, чем запускать функцию, которая перебирает ключи, согласись.

Или я чего-то не догоняю?

(Отредактировано автором: 06 Февраля, 2014 - 11:02:03)

 
 Top
Страниц (2): [1] 2 »
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« JavaScript & VBScript »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 



Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB