LINUX.ORG.RU

«Утечки» памяти в Firefox: официальный отчёт


0

0

Оказывается некоторые разработчики Mozilla Firefox до сих пор не знали(!) о печально известной ошибке, связанной с невозвращением выделенной оперативной памяти. Эта ошибка связана с тем, что выделяемая в процессе работы браузера память, запрашивается у ОС маленькими рядом идущими фрагментами, высвобождение отдельных из которых потом практически невозможно.

Stuart Parmenter предлагает несколько способов решения проблемы: выделение маленьких строк на стэке, а не в куче, выделение больших кусков памяти за один раз с дальнейшим распределением выделенного пространства под мелкие строки (как это уже сделано для layout objects) и т.д. В качестве последнего шага предлагается написать свою реализацию malloc/new, но Parmenter не считает что этим стоит заниматься, пока не опробованы другие способы.

"В качестве самой последней меры, мы могли бы полностью заменить malloc и new чем-то более лучшим. Я не думаю, что это стоит сейчас делать, пока мы не попробовали как можно больше других способов".

>>> Подробности

Ответ на: комментарий от birdie

> Через год полтора средний объём RAM на компьютере будет 1,5 - 2GB, а значит на эту проблему просто забьют.

Дык, у меня он и сейчас 2 гига -- проблема ощущается!

Спасает пока то, что Огнелис взглюкивает гораздо быстрее, чем успевает всю память сфрагментировать... :-)

Die-Hard ★★★★★
()
Ответ на: http://goog-perftools.sourceforge.net/doc/tcmalloc.html от Valeriy_Onuchin

> там в обсуждениях упоминается tcmalloc ... > Кто-нибудь может прокомментировать, что за "зvерь"?

Это САМАЯ фрагментирующая приблуда. Я не пробовал его в контексте Огнелиса, но, когда мы стукнулись в наших задачах о проблему фрагментации памяти под glibc2, то перепробовали все -- в смысле фрагментации tcmalloc даже хуже, чем malloc из glibc2.

Чисто теоретически, результат банален: либо быстро, но с фрагментацией (и делать акцент при написании аллокатора на brk или пуле), либо без фрагментации, но медленно (акцент на mmap). Это -- артефакт структуры современных операционных систем.

Если на скорость наплевать, то БСДшный malloc вполне потянет. Кстати, в случае с Огнелисом это, наверное, панацея.

Для более критичных к производительности программ (неинтерактивных) БСДшный malloc тормозит, особенно в multithread аппликухах.

Die-Hard ★★★★★
()
Ответ на: комментарий от Die-Hard

>Спасает пока то, что Огнелис взглюкивает гораздо быстрее, чем успевает всю память сфрагментировать… :-)

бедные, бедные лисоводы. ничего, будем надеяться, что через десяток-другой лет лиса можно будет не закрывать неделями, как Оперу…

%-)

mirage
()
Ответ на: комментарий от mirage

Угу - а не открывать оперу вообще можно годами! Вот это стабильность!

Ибо сколько раз наслушавшись :) пробовал - всегда выкорчевывал обратно, из говна конфет не делают!

anonymous
()
Ответ на: комментарий от anonymous

О что вас в Опере не устраивает? У меня работает, все нормально...

dpkg ★★★★
()
Ответ на: комментарий от Die-Hard

Кстати, а что если округлять все allocate'ы памяти в firefox до 4096? Тогда страницы памяти будут возвращаться полностью ;-)

Правда, как это присобачить к оператору new - ума не приложу.

birdie ★★★★★
() автор топика
Ответ на: комментарий от anonymous

> как ты думаешь, на чем реализован оператор new()?

Строго говоря, оператор new() в C++ может быть привязан к классу и, соответственно, реализован для данного класса как угодно. Хоть маллоком, хоть ареной на предварительно выделенном месте, хоть испрашиванием дополнительного места в астрале.

AlexM ★★★★★
()
Ответ на: комментарий от birdie

А по мне это вообще не проблема - ну есть фрагментация, ну теряется ~50% памяти, ну и что? Издержки аллокатора. Если тоже самое сделать на яве, то потеряется 250% и работать будет в пять раз медленнее.
Вообще, как и в случае явы, эти издержки - это плата за удобство разработки, можно конечно сделать всякие арены, аллокаторы и т.п., но поверьте, стабильности это не добавит.
Потом, фрагментация имеет такую особенность - стабилизироваться. Т.е. открыв и закрыв одну страницу один раз, потеряешь 13Mb памяти, но сделав тоже самое еще 100 раз, опять-таки потеряешь те же 13Mb памяти. Это не утечка, когда после 100 открытий ты потеряешь 1300Mb. Это вполне нормально, все C/C++ разработчики знают об этом. Странно, что этот человек это не знает.

anonymous
()
Ответ на: комментарий от Midael

да знают же они про баг с раскладками, на ЛОРЕ уже была новость про то что за устранение этого бага мозилла шайка платит 500 зеленых

anonymous
()
Ответ на: комментарий от KRoN73

>Вообще-то, уже. 512Мб - это сегодня даже в России самый лоуэнд.

уууу как же как же.

>Я со своим 1Гб на домашние машине - и то уже "нищий" :)

у меня 512 из которых 128 видео отжирает - "нищим" я себя не чувствую - собирать, отлаживать, писать ну и развлекуха типа музыку послушать, кино посмотреть более чем хватает.

free -mt
total used free shared buffers cached
Mem: 376 371 5 0 9 109
-/+ buffers/cache: 252 123
Swap: 1953 33 1919
Total: 2329 405 1924

что я делаю не так ? ;)

По теме - такому проекту как ff нужен свой аллокатор вот и все, пока они будут надеятся на libc-ый (где он лучше где он хуже - не важно) - будет все также отжирать.

alphex_kaanoken ★★★
()
Ответ на: комментарий от gaa

>можно редактировать "на лету" содержимое страницы?

Гы. Ctrl-U (Исходный текст) -> Редактируешь как хочешь, потом кнопка "Применить изменения". Страница будет показана уже с оными :)

KRoN73 ★★★★★
()
Ответ на: комментарий от KRoN73

>> можно редактировать "на лету" содержимое страницы?

> Гы. Ctrl-U (Исходный текст) -> Редактируешь как хочешь, потом кнопка "Применить изменения". Страница будет показана уже с оными :)

прикольно, посмотрю

gaa ★★
()
Ответ на: комментарий от alphex_kaanoken

>По теме - такому проекту как ff нужен свой аллокатор вот и все, пока они будут надеятся на libc-ый (где он лучше где он хуже - не важно) - будет все также отжирать.

Не факт, смотри в комментариях к статье:

Many projects look to changing memory allocators as a panacea for all problems. Following is the results of a study into a number of projects that use custom memory allocators, usually in order to improve performance. In many cases it doesn't help at all, or there would have been better performance benefits by using a general purpose allocator.

It is worthwhile keeping in mind that there may be no performance benefits from changing allocators, and it should only be done with objective testing before and after to ensure that it was worthwhile.

http://www.cs.umass.edu/~emery/pubs/berger-oopsla2002.pdf

"Многие проекты пытались решить все проблемы путем изменения распределителя памяти. По ссылке можно посмотреть результаты исследования нескольких проектов использовавших специализированные распределители, обычно для улучшения производительности. Во многих случаях это не помогало, или можно было достичь лучших результатов, используя стандартные распределители памяти"

anonymous
()
Ответ на: комментарий от anonymous

> "Многие проекты пытались решить все проблемы путем изменения распределителя памяти. По ссылке можно посмотреть результаты исследования нескольких проектов использовавших специализированные распределители, обычно для улучшения производительности. Во многих случаях это не помогало, или можно было достичь лучших результатов, используя стандартные распределители памяти"

Ну вот у Оракла, например, свой менеджер памяти (Интересно, подошел бы им стандартный ?). Веб-Браузер это тоже не тяп-ляп интерпрайз ширпотреб.

Absurd ★★★
()
Ответ на: комментарий от Absurd

кстати, сантехники недавно хвалились каким-то своим мегакрутым аллокатором, с помощью которого они postgres разогнали в 2,5 раза. мозилловцы могли бы и свистнуть, вроде тот аллокатор как и вся солярко под cddl был...

gaa ★★
()
Ответ на: комментарий от gaa

>кстати, сантехники недавно хвалились каким-то своим мегакрутым аллокатором, с помощью которого они postgres разогнали в 2,5 раза. мозилловцы могли бы и свистнуть, вроде тот аллокатор как и вся солярко под cddl был...

Я в панацеи не верю. Чтобы реально уменьшить аппетиты к памяти и увеличить перформанс надо подходить к запросам на память более индивидуально - как минимум завести несколько пулов для разных задач.

Absurd ★★★
()
Ответ на: комментарий от Absurd

>> кстати, сантехники недавно хвалились каким-то своим мегакрутым аллокатором, с помощью которого они postgres разогнали в 2,5 раза. мозилловцы могли бы и свистнуть, вроде тот аллокатор как и вся солярко под cddl был...

> Я в панацеи не верю. Чтобы реально уменьшить аппетиты к памяти и увеличить перформанс надо подходить к запросам на память более индивидуально - как минимум завести несколько пулов для разных задач.

ну а хрен его знает, может он и для огнелиса подойдёт?

gaa ★★
()
Ответ на: комментарий от birdie

> Кстати, а что если округлять все allocate'ы памяти в firefox до 4096? Тогда страницы памяти будут возвращаться полностью ;-)

Нет, в brk- базированных аллокаторах память можно отдавать системе лишь "с конца". В этом и состоит проблема фрагментации в таких системах.

В mmap - базированных аллокаторах (как, например, во фряхе) проблемы фрагментации (практически) не существует -- она сама все округляет как надо. Но работает в разы медленнее -- просто за счет дороговизны mmap/munmap

К Огнелису БСДшный маллок прикрутили, могу ссылку кинуть, если надо. Вроде, работает, хотя я сам не пробовал -- у меня Огнелис обычно валится задолго до проблем с памятью.

> Правда, как это присобачить к оператору new - ума не приложу.

И Гнутый компилер, и Интеловский для new юзают маллок, так что ничего специально присобачивать не надо, просто прелоад на маллок/реаллок/фри.

Die-Hard ★★★★★
()
Ответ на: комментарий от gaa

>>> кстати, сантехники недавно хвалились каким-то своим мегакрутым аллокатором, с помощью которого они postgres разогнали в 2,5 раза. мозилловцы могли бы и свистнуть, вроде тот аллокатор как и вся солярко под cddl был...

Если мне не изменяет мой склероз, это и был tcmalloc.

>> Я в панацеи не верю. Чтобы реально уменьшить аппетиты к памяти и увеличить перформанс надо подходить к запросам на память более индивидуально - как минимум завести несколько пулов для разных задач.

Верно мыслишь!

>ну а хрен его знает, может он и для огнелиса подойдёт?

Нет, там с фрагментацией проблем еще больше.

Die-Hard ★★★★★
()
Ответ на: комментарий от Die-Hard

>> Правда, как это присобачить к оператору new - ума не приложу.

>И Гнутый компилер, и Интеловский для new юзают маллок, так что ничего специально присобачивать не надо, просто прелоад на маллок/реаллок/фри.

Это неправильно. В C++ часто используются мелкие объекты, состоящие из одного указателя на таблицу виртуальных функций. Размещать такое барахло в malloc-куче нерационально.

Absurd ★★★
()
Ответ на: комментарий от anonymous

Уря, умный аноним! Тут просто люди прикалываются. У нас тоже шэф всегда говорит своими словами: как бы так сделать чтобы ничего не делать, но чтобы всё работало? Так и тут, может чего-нибудь в филармонии подправить? Может каждый начнёт свои былоаллокатороподелки писать для своих программ нихрена не шаря ни в аллокаторах ни в поделках, наверное в быдле много шарят. Истинно, любой лох свой аллокатор напишет, только после этого пожалуйста исследования проведите перед внедрением оного. Дабы потом от смеха народ не мёр. Раз уж вы все такие умные и OSS наше всё, то флаг в руки glibc аллокатор на экран и ищите! Всем польза будет.

alx_me ★★☆
()
Ответ на: комментарий от KRoN73

>потом кнопка «Применить изменения»

/me пошло убиваццо апстену. а также выкидывать полуначатый скрипт «advanced html editor».

авотфиг. /me вернулось. у /me есть полурабочий вариант javascript debugger'а со шлюхами и блэ… э… с брякпоинтами и пошаговым исполнением. торрррмозит, но дебажить можно, если очень нужно. а больше ни у кого из оперовцев такого нет. вот. %-)

mirage
()
Ответ на: комментарий от Absurd

>Ну вот у Оракла, например, свой менеджер памяти (Интересно, подошел бы им стандартный ?). Веб-Браузер это тоже не тяп-ляп интерпрайз ширпотреб.

Тут проблема не в ширпотреб/не-ширпотреб на самом деле. Нельзя что-то получить из ничего - получив выигрыш на одних задачах, ты неизбежно получишь проигрыш на других. Вполне вероятно, что внутри БД в основном используются очень специфические алгоритмы и структуры данных, для которых написание своего аллокатора даст значительный выигрыш. Диапазон структур данных внутри браузера должен быть, во-первых, шире, а во-вторых, намного больше подходить к стандартным условиям на которые заточены стандартные аллокаторы.
Вообще, я использую файрфокс довольно интенсивно - открываю много вкладок и т.п. и особых проблем с памятью не испытывал, хотя у меня тоже 512М с видео отображаемым в основную память.

anonymous
()
Ответ на: комментарий от anonymous

> получив выигрыш на одних задачах, ты неизбежно получишь проигрыш на других.

задача одна - нетормозящий огнелис.

> Вообще, я использую файрфокс довольно интенсивно - открываю много вкладок и т.п. и особых проблем с памятью не испытывал, хотя у меня тоже 512М с видео отображаемым в основную память.

самовнушение - это сила

gaa ★★
()
Ответ на: комментарий от anonymous

>>Ну вот у Оракла, например, свой менеджер памяти (Интересно, подошел бы им стандартный ?). Веб-Браузер это тоже не тяп-ляп интерпрайз ширпотреб.

> Тут проблема не в ширпотреб/не-ширпотреб на самом деле. Нельзя что-то получить из ничего - получив выигрыш на одних задачах, ты неизбежно получишь проигрыш на других

Ну вот я и пишу - для подзадачи для которой нужен аллокатор A использовать аллокатор A, а для подзадачи где нужен аллокатор B использовать аллокатор B, а не лепить везде malloc() для десятков короткоживущих объектов JavaScript размером по 32-64 байта. Разные открытые страницы тоже неплохо бы изолировать друг от друга, чтобы при закрытии страницы можно было бы освободить сразу большой непрерывный чанк.

Absurd ★★★
()
Ответ на: комментарий от Absurd

> Это неправильно. В C++ часто используются мелкие объекты, состоящие из одного указателя на таблицу виртуальных функций. Размещать такое барахло в malloc-куче нерационально.

Разумеется, если объект не заимает место в памяти, то она ему (как правило) не выделяется. Хотя и это зависит от версии компилятора / библиотеки.

Для выделеления памяти в куче оператор new использует malloc. Так понятно?

Die-Hard ★★★★★
()
Ответ на: комментарий от Die-Hard

>> Это неправильно. В C++ часто используются мелкие объекты, состоящие из одного указателя на таблицу виртуальных функций. Размещать такое барахло в malloc-куче нерационально.

>Для выделеления памяти в куче оператор new использует malloc. Так понятно?

Это Вам чего-то непонятно. Полиморфный объект всегда должен создаваться с помощью new, даже если в нем нет данных. В этом случае он будет иметь размер 4 байта на указатель pVTable + выравнивание. Размещать большое количество таких объектов при помощи malloc(sizeof(pVTable)) - это неправильно. Вообще, стандарт С++ не рекоммендует реализовывать new через malloc, так как сущности в C++ мельче чем в C.

Absurd ★★★
()
Ответ на: комментарий от anonymous

>Many projects look to changing memory allocators as a panacea for all problems. Following is the results of a study into a number of projects that use custom memory allocators, usually in order to improve performance. In many cases it doesn't help at all, or there would have been better performance benefits by using a general purpose allocator.

смотря что за проект: в большинстве случаев достаточно переработать алгоритмы чтобы они не требовали много раз выделять память и так далее - с этим согласен. но есть такие проекты - тот же огнелис что нужно именно свой аллокатор писать - именно благодаря существующей code-base у него.

>"Многие проекты пытались решить все проблемы путем изменения распределителя памяти. По ссылке можно посмотреть результаты исследования нескольких проектов использовавших специализированные распределители, обычно для улучшения производительности. Во многих случаях это не помогало, или можно было достичь лучших результатов, используя стандартные распределители памяти"

Спасибо, читать умею ;)))

alphex_kaanoken ★★★
()
Ответ на: комментарий от alphex_kaanoken

>смотря что за проект: в большинстве случаев достаточно переработать алгоритмы чтобы они не требовали много раз выделять память и так далее - с этим согласен. но есть такие проекты - тот же огнелис что нужно именно свой аллокатор писать - именно благодаря существующей code-base у него.

да к тому же, если сложно детерминировать (а в фф именно так) порядок и частоту выделения, то тут спасет только свой аллокатор - например на mmap - который бы создавал несколько пулов для объектов разного объема - ну и имел хитрую политику хеширования - я не говорю про то что в принципе можно было б добавить политику пересмотра пула при запросе - те когда сам огнелис в определенных случаях будет решать и при надобности переносить куски памяти в целях либо выделения памяти в случае ее нехватки, либо в целях фрагментации. Короче, к чему я клоню - к тому что во многих случаях надеятся на libc-ый аллокатор не стоит, а то так может и 6 гигов оперативки не хватить ;)))

alphex_kaanoken ★★★
()
Ответ на: комментарий от alphex_kaanoken

> если сложно детерминировать (а в фф именно так) порядок и частоту выделения, то тут спасет только свой аллокатор - например на mmap - который бы создавал несколько пулов для объектов разного объема - ну и имел хитрую политику хеширования - я не говорю про то что в принципе можно было б добавить политику пересмотра пула при запросе - те когда сам огнелис в определенных случаях будет решать и при надобности переносить куски памяти в целях либо выделения памяти в случае ее нехватки, либо в целях фрагментации.

hoard посмотри, ссылка выше.

anonymous
()
Ответ на: комментарий от anonymous

> Кроме openbsd-malloc, для отдачи памяти можно использовать hoard (http://www.hoard.org/) c SUPERBLOCK_SIZE = 4K-64K

там по умолчанию же идёт 64K, память не отдаёт, дней пять интенсивно у меня поработал и огнелис стал жутко тормозить :(

anonymous
()
Ответ на: комментарий от anonymous

> Попробовал SUPERBLOCK_SIZE=4K - всё равно не отдаёт!

LD_PRELOAD срабатывает? ему надо указывать полный путь к библиотеке:

$ LD_PRELOAD=/full/path/to/libhoard.so firefox

C libhoard, SUPERBLOCK_SIZE = 4K:

1. после запуска с about:blank:

  PID    VSZ  RSS COMMAND
22019  99388 30568 /usr/lib/firefox-1.5.0.12/firefox-bin -UILocale ru

2.  открыли 30 вкладок из Talks:

22019 168756 79768 /usr/lib/firefox-1.5.0.12/firefox-bin -UILocale ru

3. закрыли все вкладки, оставили about:blank:

22019 131564 63812 /usr/lib/firefox-1.5.0.12/firefox-bin -UILocale ru


С libopenbdsmalloc:

1. после запуска с about:blank:

22833 76032 29100 /usr/lib/firefox-1.5.0.12/firefox-bin -UILocale ru

2. после тех же вкладок:

22833 152080 81752 /usr/lib/firefox-1.5.0.12/firefox-bin -UILocale ru

3. закрыли все, оставили about:blank:

22833 112472 45648 /usr/lib/firefox-1.5.0.12/firefox-bin -UILocale ru

anonymous
()
Ответ на: комментарий от anonymous

слова «у оперовцев» не увидел? когда запустишь эту хренотень под Оперой — возвращайся. пока — свободен.

mirage
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.