avva: (Default)
[personal profile] avva
В обсуждении о компиляторах всплыл полезный совет: иногда об освобождении памяти лучше и не думать.
Memory leaks are the least of your problems in a compiler; it's not like it's a long running process. You run it, it terminates, the OS cleans up for you.
I did some work on SDCC years ago and it went through a brief "lets use a garbage collector!" phase until everybody realized it was contributing negative value. It was more efficient to simply free memory where convenient and leak it where not.

... и дальше:

I believe it's well known that compilers leak memory like sieves. But the thing is, it doesn't really matter in most contexts. If the leak is linear with the size of the program you're probably fine and no one will notice anyway.


(кстати, всю эту дискуссию о компиляторах стоит проглядеть: там есть немало отличных ссылок)

Это очень полезный совет: иногда в языке и среде, которые казалось бы требуют тщательной работы с malloc()/free() или их эквивалентами, про free() можно просто забыть и не делать, если программа выполняется быстро и не требует очень много памяти. Полезный потому, что привыкший к тщательной дисциплине программист может об этом просто не подумать.

Но мне это напомнило еще вот какую давнюю мысль: по-моему, намного реже, чем следовало бы, программисты на языках с эксплицитной обработкой памяти пользуются отдельными кучами. "Отдельная куча" (private heap) означает всего лишь возможность отводить память в отдельном месте, идентифицируемом каким-то ключом. Например, в Win32 есть функции: HeapCreate() создает новую кучу и возвращает идентификатор, HeapAlloc() - вместе с желаемым размером получает идентификатор кучи и отводит память именно в ней, HeapFree() - очевидно, и HeapDestroy() - удалить всю кучу вместе со всей памятью в ней, которой еще не сделали HeapFree().

Иногда это называют не кучей, а "ареной", но суть та же. На самом деле самое главное во всем этом - возможность удалить кучу одним махом, потому что если она есть, и если вся память, что отводится из кучи, вместе не слишком велика, то отдельно освобождать ничего не надо. Собственно, можно обойтись без free() вообще. Куча тогда превращается в сплошной кусок памяти (или связанный список таких кускок, если надо), а malloc() становится тривиальным, он просто двигает указатель на свободную часть кучи.

Очень часто значительная часть логики программы устроена так. Начинаем строить какой-то объект (в C это может быть сложная структура, неважно), он в свою очередь создает и инициализирует другие объекты внутри себя, или целые массивы, или списки, или еще что, неважно. Все это по цепочке вложено друг в друга, а после создания еще начинает как-то работать и двигаться вместе, вызывать друг друга, хранить какую-то информацию итд. В конце концов объект выполнил свое дело и удаляется, по цепочке вначале удаляя все вложенные объекты и контейнеры и освобождая всю память. Все это делается через сложный танец new/delete или malloc/free. Но если вся память, что нужна объекту и всему, что в него вложено, не слишком велика на протяжении его жизни, то с помощью отдельной кучи только для этого объекта и всего, что в него вложено, можно избежать всего этого сложного танца и сделать код одновременно намного проще, лучше защищенным от ошибок и даже быстрее - да-да, быстрее, чем обычный танец malloc/free. Единственное, чем платишь - повышенным расходом памяти во время жизни объекта, да и то часто налог этот весьма невелик.

Я уже лет десять как не пишу под Windows, но до сих пор помню, какими полезными и правильными были функции для работы с отдельными кучами. Конечно, каждый может сам на коленке сколотить что-то свое для этого; я не раз такое встречал, да и сам несколько раз писал. Но все же меня удивляет, что в Юниксе нет стандартного интерфейса для этого дела. И я не раз видел исходники библиотек или приложений, которые бы этот простой прием сильно упростил и улучшил.

Date: 2009-11-21 10:20 pm (UTC)
From: [identity profile] http://users.livejournal.com/_navi_/
А чем конкретно полезно это специфичное WinAPI для использования арен? Тем, что за тебя уже определён какой-то кастомный HeapAlloc, который наверняка содержит в себе что-то лишнее для данной проблемы, как минимум работу с фри-листами (вместо того, чтобы дать программисту возможность задать оптимальный алгоритм аллокации для арены)?

Date: 2009-11-21 11:01 pm (UTC)
From: [identity profile] avva.livejournal.com
Полезно в первую очередь тем, что оно есть и стандартное, и тем самым привлекает внимание программиста, становится частью его стандартного арсенала итд.

То, что HeapAlloc() использует свой конкретный алгоритм, и в частности не так быстр, как, например, алгоритм сплошной аллокации без освобождения - в 99.99% случаев абсолютно неважно и никакой роли не играет. Давайте не забывать слова Кнута о преждевременной оптимизации.

(no subject)

From: [identity profile] http://users.livejournal.com/_navi_/ - Date: 2009-11-21 11:16 pm (UTC) - Expand

(no subject)

From: [identity profile] avva.livejournal.com - Date: 2009-11-22 01:19 am (UTC) - Expand

(no subject)

From: [identity profile] lazyreader.livejournal.com - Date: 2009-11-22 05:31 am (UTC) - Expand

(no subject)

From: [identity profile] avva.livejournal.com - Date: 2009-11-22 05:35 am (UTC) - Expand

Date: 2009-11-21 10:38 pm (UTC)
From: (Anonymous)
Мне нравится что я понимаю о чем ты говоришь. Я начал изучать C/С++ нерегулярно и для себя, непрограммиста (вернее в далеком прошлом).
Как не крути это высокая поэзия (разговоры о распределении памяти), хотя, видимо программирование уже давно ремесло.
Вообщем, мы все умрем:)

Date: 2009-11-21 10:52 pm (UTC)
From: [identity profile] egorfine.livejournal.com
Сейчас программирую под айфон - приходится очень внимательно относиться к памяти. Даже местный memory manamement в objc не спасает, надо ручками. Всего 128 мег памяти, из них приложению доступно в самый максимум сто мег.

Date: 2009-11-21 10:59 pm (UTC)
From: [identity profile] avva.livejournal.com
Вы почитайте вот, вдохновитесь:

http://jordanmechner.com/wp-content/uploads/1989/10/popsource009.pdf

Особенно стр. 4 этого документа. Это к вопросу о "максимум сто мег".

(no subject)

From: [identity profile] ygam.livejournal.com - Date: 2009-11-21 11:03 pm (UTC) - Expand

(no subject)

From: [identity profile] breqwas.livejournal.com - Date: 2009-11-22 01:38 am (UTC) - Expand

(no subject)

From: [identity profile] avva.livejournal.com - Date: 2009-11-22 01:45 am (UTC) - Expand

не вдохновился

From: [identity profile] egorfine.livejournal.com - Date: 2009-11-22 06:47 pm (UTC) - Expand

Re: не вдохновился

From: [identity profile] laformica.livejournal.com - Date: 2009-11-23 07:16 pm (UTC) - Expand

Re: не вдохновился

From: [identity profile] egorfine.livejournal.com - Date: 2009-11-23 08:04 pm (UTC) - Expand

Re: не вдохновился

From: [identity profile] laformica.livejournal.com - Date: 2009-11-23 11:16 pm (UTC) - Expand

Re: не вдохновился

From: [identity profile] laformica.livejournal.com - Date: 2009-11-24 03:01 pm (UTC) - Expand

Date: 2009-11-23 08:04 am (UTC)
From: [identity profile] plakhov.livejournal.com
в самый максимум сто мег
Под Nintendo DS попробуйте пописать :)

Date: 2009-11-21 11:13 pm (UTC)
From: [identity profile] izblank.livejournal.com
Мы сейчас похожую стратегию к нашей базе данных думаем применить. Вместо того, чтобы заботиться о партициях, foreign keys, и прочих заморочках, просто посылать все новое в другую базу, а старую по происшествии какого-то времени дропнуть, и все дела. И так каждый год.

Date: 2009-11-23 12:32 am (UTC)
From: [identity profile] glex1.livejournal.com
А мы просто запускаем очистку db от мусора раз в месяц

(no subject)

From: [identity profile] izblank.livejournal.com - Date: 2009-11-23 08:06 pm (UTC) - Expand

Date: 2009-11-21 11:35 pm (UTC)
From: (Anonymous)
Как не профи я все-таки не понимаю, почему бы os не чистить автоматически то что было сделано приложением. Такой большой брат следит за всеми malloc/new и потом все чистит.Есть что-то невозможное в этом?

Date: 2009-11-22 12:26 am (UTC)
From: (Anonymous)
Она и чистит. По завершению процесса.
До завершения она ведь не знает, когда именно что можно очистить.

Date: 2009-11-22 12:27 am (UTC)
wizzard: (Default)
From: [personal profile] wizzard
Когда приложение завершилось - мы точно знаем, что ему _ничего_ не нужно. Пока оно работает - ему что-то нужно, а что-то не нужно. Сложно именно определить, что именно.

Date: 2009-11-22 12:47 am (UTC)
From: (Anonymous)
Хорошо, запустили процесс, определили для процесса предельные величины использования памяти, типа, всего допустимой для выделения памяти/кол-во процессов. Дальше нужно os должна следить не за абсолютными величинами, а за динамикой и new - вдруг программер ошибся, возвращает указатели на аллоокированные куски из процедуры и т.д. можно придумать некие предыгадывающие механизмы, которые говорили бы os что девелопер ох..л или прога неправильно работает. По-моему, кол-во таких ситуаций конечно.

Date: 2009-11-22 01:17 am (UTC)
From: [identity profile] avva.livejournal.com
Есть утилиты для отладки, которые именно так работают: следят за динамикой итд. Операционной системе в целом нет смысла этим заниматься, потому что она ничего интересного о приложении не знает, и ничего с ним не может сделать, кроме как убить; но если там какой-то баг или память сильно протекает, оно скорее всего и так произойдет. А если бы ОС на основании динамики выделения памяти пыталась убить приложение, то поубивала бы неизбежно кучу легитимных приложений с необычной динамикой памяти.

Date: 2009-11-22 01:11 am (UTC)
From: [identity profile] msh.livejournal.com
Memory leaks are the least of your problems in a compiler; it's not like it's a long running process. You run it, it terminates, the OS cleans up for you.

недавний пост одного из моих friends

Сборка libtorrent-rasterbar 0.14.6 уложила мне виртуальную машину, run out of swap space. Гиг памяти и гиг свопа.

Date: 2009-11-22 01:14 am (UTC)
From: [identity profile] avva.livejournal.com
Это почти наверняка линкер (или он запустил слишком много параллелизации).

(no subject)

From: [identity profile] msh.livejournal.com - Date: 2009-11-22 01:34 am (UTC) - Expand

(no subject)

From: [identity profile] avva.livejournal.com - Date: 2009-11-22 01:47 am (UTC) - Expand

(no subject)

From: [identity profile] msh.livejournal.com - Date: 2009-11-22 03:29 am (UTC) - Expand

(no subject)

From: [identity profile] egorfine.livejournal.com - Date: 2009-11-22 06:49 pm (UTC) - Expand

(no subject)

From: [identity profile] max630.livejournal.com - Date: 2009-11-22 05:19 am (UTC) - Expand

Date: 2009-11-22 01:43 am (UTC)
nine_k: A stream of colors expanding from brain (Default)
From: [personal profile] nine_k
Что до раздельных куч, то этот приём активно применялся, помнится, в Doom. Как раз для быстрой очистки всех ненужных объектов.
А ещё в древнем паскале (не помню версии, может, это ещё от Вирта идёт) для кучи были процедуры mark и release. Говоришь mark, делаешь какие хошь аллокации, говоришь release, куча сдувется обратно до состояния на момент mark. Но с раздельными удобнее.

Date: 2009-11-22 11:32 am (UTC)
From: [identity profile] vakhitov.livejournal.com
В TP 3.x вроде было?

Date: 2009-11-22 04:16 am (UTC)
From: [identity profile] m0riarty.ya.ru (from livejournal.com)
Это все правда, но не надо забывать, что такой подход - не серебряная пуля. Кромен памяти еще и другие ресурсы есть, которые тоже надо освобождать.

Date: 2009-11-22 05:36 am (UTC)
From: [identity profile] avva.livejournal.com
Интересно, а серебряные пули вообще бывают, ну буквально то есть? Серебро не слишком ли мягкий металл для пули? (может, я несу бред - я в этом ничего не понимаю)

(no subject)

From: [identity profile] msh.livejournal.com - Date: 2009-11-22 05:45 am (UTC) - Expand

(no subject)

From: [identity profile] old-radist.livejournal.com - Date: 2009-11-22 09:00 am (UTC) - Expand

(no subject)

From: [identity profile] m0riarty.ya.ru - Date: 2009-11-22 05:57 am (UTC) - Expand

(no subject)

From: [identity profile] lykac.livejournal.com - Date: 2009-11-22 07:00 am (UTC) - Expand

(no subject)

From: [identity profile] deemon.livejournal.com - Date: 2009-11-22 07:44 am (UTC) - Expand

(no subject)

From: [personal profile] a_p - Date: 2009-11-22 01:05 pm (UTC) - Expand

Date: 2009-11-22 04:59 am (UTC)
From: [identity profile] rxvm.livejournal.com
4G памяти - это на самом деле очень мало. Я сталкивался с тем, что некий нехорошиий (сгенерированный) С-код в несколько сотен строк крешится на некоторых уважаемых компиляторах из-за нехватки 32-битного адресного пространства.

Память, в отличие от run-time, плохо масштабируется: в какой-то момент уже небольшой рост приводит к тому, что процесс падает или уходит в свап. Это, в частности, одна из проблем в model checking: ты можешь согласиться с тем, чтобы ждать недели, пока экспоненциальный алгоритм даст тебе ответ, но с экспоненциального размера моделью просто невозможно работать.

Private heap - хорошая штука.

Date: 2009-11-22 05:08 am (UTC)
From: (Anonymous)
Кому надо, делает не на коленке, а на столе, как человек :)

Например, в рантайме апача имеется соответствующая подсистема. В веб-сервере (и в любом stateless сервере) это единственная разумная стратегия работы с памятью. Память, связанная с запросом, живет не дольше, чем сам запрос. В апаче все еще несколько удобнее: пул может быть частью другого пула. Можно прибить пул и вместе с ним освобождаются все его дети. А освобождение кусков внутри пула не предусмотрено, ибо незачем.

Пы. Сы. В Калифорнийщину по поводу Хрома ездили?

Date: 2009-11-22 05:19 am (UTC)
From: [identity profile] avva.livejournal.com
Да, вебсервер - почти идеальная модель для такой работы с памятью.

Нет, я не работаю над Хромом и ездил не за этим.

(no subject)

From: [identity profile] msh.livejournal.com - Date: 2009-11-22 05:41 am (UTC) - Expand

(no subject)

From: (Anonymous) - Date: 2009-11-22 07:43 am (UTC) - Expand

(no subject)

From: [identity profile] msh.livejournal.com - Date: 2009-11-22 06:55 pm (UTC) - Expand

Date: 2009-11-22 07:36 am (UTC)
From: [identity profile] shure.livejournal.com
Неужели нет такой GLPL library ? Если нет - давайте делать.
Несколько лет назад я вставил BoehmGC в большой коммерческий проект. Вот несколько результатов:
1) С тех пор, я отлаживаю все memory leaks в фирме.
2) С тех пор, я отлаживаю все memory corruptions в фирме (что хуже!).
3) Каждый раз отлаживая все это я очень опасаюсь обнаружить реально тежёлую проблему с Boehm. Вынуть то его нельзя! Нервы-ж знаете не железные.
Так что решение с private heaps кажется мне отличным компромиссом для многих случаев.

Date: 2009-11-22 07:46 am (UTC)
vitus_wagner: My photo 2005 (Default)
From: [personal profile] vitus_wagner
Как нету? Apache Portable Runtime. Она, правда, Apache License, а не GPL, но хрен ли разницы.

(no subject)

From: [identity profile] potan.livejournal.com - Date: 2009-11-23 10:32 am (UTC) - Expand

Date: 2009-11-22 12:19 pm (UTC)
From: [identity profile] prepod-urgu.livejournal.com
Относительно утечек памяти есть вот какие рассуждения.

1. В эксплорере безбожно течёт память из-за того, что DOM весь COMовский, а жабаскрипт выполняется из под актив-скриптинг с высвобождением памяти, не учитывающим циклические ссылки между "внутри" и "наружи". Из-за этого для того, чтобы сделать прилагу с хорошим юзер-экспириенс, требуется упираться, чтобы память не текла, иначе куча растёт и фрагментируется, вокринг-сэпэйс растёт и пэйдж-фолты сильно снижают производительность. А потом заканчивается адресное пространство и всё.

2. В COMе для DCOMа требуется всем ин-проц компонентам сделать хост-процесс. В результате, либо много процесов, либо у каждого компонента в хост-процессе своя куча, и всё.

В общем, управление памятью, если его принимать последним рассуждением, становится жутким геморроем.

Date: 2009-11-22 01:16 pm (UTC)
a_p: (Default)
From: [personal profile] a_p
мне кажется, что введение дополнительного уровня в иерархии аллокаций (то есть приватных хипов) в Виндоус и отсутствие его же в Юниксе как-то связано с тем, что в Юниксе многие проблемы решаются заведением отдельных процессов (то есть, "эквивалент" отдельного хипа имеет вид - завели процесс, поработали-поаллокировали, потом убили с высвобождением памяти), в Виндоус же процесс тяжелее, откуда (в том числе) и треды стали гораздо нужнее. Кстати, довольно важное преимущество использования множественных хипов под Виндоус - в том, что их можно заводить потредно, а это позволяет не сериализировать работу с выделением/освобождением памяти из хипа.

Date: 2009-11-23 05:54 am (UTC)
From: [identity profile] kmmbvnr.livejournal.com
А по факту, в unix, кто кроме web приложений и shell скриптов кто так поступает?

(no subject)

From: [personal profile] a_p - Date: 2009-11-23 08:19 am (UTC) - Expand

(no subject)

From: [identity profile] potan.livejournal.com - Date: 2009-11-23 10:35 am (UTC) - Expand

Date: 2009-11-22 04:18 pm (UTC)
From: (Anonymous)
>>Но если вся память, что нужна объекту и всему, что в него вложено, не слишком велика на протяжении его жизни, то с помощью отдельной кучи только для этого объекта и всего, что в него вложено, можно избежать всего этого сложного танца и сделать код одновременно намного проще, лучше защищенным от ошибок и даже быстрее - да-да, быстрее, чем обычный танец malloc/free

Это наверно не подойдет для того случая,когда обьект создавался другим программистом.Как я смогу узнать размер памяти необходимой для работы обьекта если я его не создавал?

Date: 2009-11-22 04:23 pm (UTC)
From: [identity profile] cmm.livejournal.com
а кто-то сказал что размер той отдельной кучи ограничен?  время её жизни ограничено, только и всего.

Date: 2009-11-23 05:48 am (UTC)
From: [identity profile] kmmbvnr.livejournal.com
Да, наверное просто имеет смысл использовать раздельные кучи для повышения живучести документоориентированного приложения. Каждый документ в отдельную кучу, где-то во время работы конечно придется память чистить, но при закрытии документа гарантированно отчищать все.

Date: 2009-11-23 08:11 am (UTC)
From: [identity profile] plakhov.livejournal.com
Мы сотоварищи довольно большой memory-bound проект написали полностью на аренах. Я был очень доволен. Здесь в комментариях звучали слова "максимум сто мег", у нас было максимум три.

Особенно мне нравилось даже не "отсутствие утечек" (по-моему, для опытного программиста это все-таки никогда не проблема), а доказательность всего кода, скорость операций с памятью и красота реализации weak reference'ов, без каких-либо tradeoff'ов.

Если интересно про weak reference'ы и стратегию освобождения памяти, не противоречащую этим идеям: http://plakhov.livejournal.com/77787.html

Date: 2009-11-23 07:27 pm (UTC)
From: [identity profile] laformica.livejournal.com
Вот подумалось, а интересно, если взять набор типовых алгоритмов и померять производительность и расход памяти в случае реализации на языке c GC и без, но с аренами, какие результаты будут?

December 2025

S M T W T F S
  123 4 56
78 9 10 11 1213
1415 1617181920
21 22 23 24 2526 27
28293031   

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Dec. 29th, 2025 10:11 am
Powered by Dreamwidth Studios