Текущий архив: 2004.05.30;
Скачать: CL | DM;
ВнизВпечатления о memory maneger е. Найти похожие ветки
← →
Тимохов © (2004-05-11 10:50) [0]Хочу поделиться впечатлениями.
На волне вчерашних обсуждений, что Дельфи - г, т.к. не дает возможность узанать жив объект или нет решил почитать статью http://rsdn.ru/article/Delphi/memmanager.xml и также посмотреть getmem.inc. Я и раньше пытался делать это - но без знаний, полученных из рихтера, никак не получалось.
Все это на меня произвело сильное впечатление:
1. Нефигово навернутая логика (Борланд крут :)))
2. Нефигово заоптимизировано (вообще чума).
Второй пункт я понял после того, как на машине 1000мг ~700мбОЗУ провел опыт:
1. Есть 100 классов все с разными InstanceSize, которые содержать простые типы - не строки, не дин. массивы...
2. В случайным образом они создаются и удаляются (вероятность создания чуть больше).
2млн циклов прошло за 0.8 секунд. В конце в списке оказалось около 500000 тыс объектов.
Меня все это сильно впечатлило:
1. По идее должна бы быть нефиговая фрагментация (все классы разного размера). Фиг бы с ней, но из-за этого по идее после опыта должно было бы быть занято места больше, чем на 500000 объектов. Примерные расчеты на пальцах показали, что места занято совсем немного больше. Т.е. с фрагментацией манагер справляется отлично - упешно использует дырки.
2. Посмотрев на getmem.inc и не увидев asm у меня было ощущение, что это не может быстро работать. Оказалось может.:)))
Теперь вопрос
Как вы думаете по каким причинам getmem.inc использует LocalAlloc, а не HeapAlloc? Вроде в MSDN сказано, что LocalAlloc все равно обращается к куче, но делает это медленнее, чем HeapAlloc.
← →
wicked © (2004-05-11 11:21) [1]имхо LocalAlloc - рудимент еще от делфи 1....
он опирался на win 3.1 api, а там heap функций просто не было.....
тем более, учитывая то, что memory manager реже обращается к LocalAlloc и другим функциям, то и негативный эффект от меньшей производительности не так заметен...
(моё большое имхо) с другой стороны, остальные библиотеки и классы слишком сильно опираются на этот сверхбыстрый memory manager, и поэтому в ряде случаев остальные вещи (строки например) могут работать не совсем оптимально...
← →
Тимохов © (2004-05-11 11:34) [2]
> wicked © (11.05.04 11:21) [1]
> в ряде случаев остальные вещи (строки например) могут работать
> не совсем оптимально...
Согласен.
Вообще говоря заставить классы работать с другим манагером памяти вполне можно (переопределить NewInstance).
А вот строки заставить работать с другим манагером памяти вряд ли можно. Только на pchar переходить.
← →
wicked © (2004-05-11 11:37) [3]можно...
советую глянуть на функции SetMemoryManager/GetMemoryManager... по крайней мере на 6 билдере они есть...
в своё время я так пробовал отловить утечки памяти (наивный ;))...
← →
Тимохов © (2004-05-11 11:44) [4]
> wicked © (11.05.04 11:37) [3]
> можно...
Можно, но тогда вся программа станет работать с другим манагером.
Я имел виду, чтобы она строка работала с одним манагером, а другая с другим. Можно, конечно, манагер переключать какждый раз, но это маразм.
Поэтмоу я это назваю неззя.
← →
Mystic © (2004-05-11 12:09) [5]На самом деле LocalAlloc там вызывается только в одном месте --- для выделения массива из 100 описателей блоков. Эта память никогда не будет возвращена в качестве результата GetMem --- только для внутренних целей. Вызывается раз в год, два раза на пасху, поэтому в принципе не важно, что там стоит. Тем более, что LocalAlloc(LMEM_FIXED, Size) это просто сокращение для HeapAlloc(GetProcessHeap(), Size). Так что тут какую функцию поставить --- дело вкуса.
Имеет смысл почитать еще первый том Кнута --- там написано много чего про различные менеджеры памяти, и становиться понятным, например, введение указателя блуждающего указателя ROVER (упражнение 7).
← →
Тимохов © (2004-05-11 12:17) [6]
> Mystic © (11.05.04 12:09) [5]
Спасибо.
Отличная статья!
Про rover я еще почитаю. Понял пока не очень:)))
Про LocalAlloc.
Согласен, что вызывается редко (проверил).
Действительно, наверное в данном контексте не важно что вызывать.
← →
PVOzerski © (2004-05-11 12:24) [7]А вот во FreePascal/win32 используется именно HeapAlloc.
2Тимохов © (11.05.04 10:50): а не слабО перекомпилировать свой тестик под FPC и запустить?
← →
Romkin © (2004-05-11 12:29) [8]Менеджер памяти Delphi оптимизирован именно для работы с большим количеством мелких объектов с коротким временем жизни.
Когда-то я видел стравнительные тесты с С++, и именно в этом тесте Delphi опередил ВСЕ компиляторы С++, и заметно.
← →
Тимохов © (2004-05-11 12:33) [9]
> Romkin © (11.05.04 12:29) [8]
гениальное изобретение данного манагера памяти - хранить свободные маленькие блоки - лекго прямым доступом найти свободный блок.
хотя Андрей вроде сказал, что про манагеры памяти много написано в кнуте. Возможно борланд позаимствовал.
Но все равно - здорово сделано.
← →
Mystic © (2004-05-11 13:14) [10]У Кнута там далеко довольно хороший анализ методов (на 1975 год). Ничего принципиально нового с тех пор не появилось, а вот менеджер памяти Delphi --- хорошее сочетание комбинаций этих идей.
С менеджером памяти Delphi легко эксперементировать --- нужно только оформить getmem.inc в виде отдельного модуля и рарегистрировать свой менеджер памяти... Только не забіть написать строчку в начале
function SysFreeMem(p: Pointer): Integer; forward;
по поводу asm-а --- компиляторы сравнительно неплохо сейчас кодирую выражения, с ними соперничать иногда сложно даже на asm-е...
← →
VaS (2004-05-11 15:01) [11]Быстро-то быстро... Но вот что делать с самим Делфи, который использует тот же самый менеджер? Build группы из 14 немаленьких проектов приводит к захвату 390М памяти, которые Делфи не отдаст уже никогда и ни за что. В результате на 512М рамы приходиться перезапускать Делфи для нормальной дальнейшей работы с 1-2 проектами.
← →
Тимохов © (2004-05-11 15:08) [12]
> приводит к захвату 390М памяти, которые Делфи не отдаст
> уже никогда
Опять же если не ошибаюсь на основе анализа getmem.inc я так понимаю, что манагер отдает память и очень радостно если количесвто свободных блоков превысит некое число.
Может проблема в самом дельфе.
Никогда не проверял билд 14 немаленьких проектов.
← →
Тимохов © (2004-05-11 15:08) [13]
> приводит к захвату 390М памяти, которые Делфи не отдаст
> уже никогда
Опять же если не ошибаюсь на основе анализа getmem.inc я так понимаю, что манагер отдает память и очень радостно если количесвто свободных блоков превысит некое число.
Может проблема в самом дельфе.
Никогда не проверял билд 14 немаленьких проектов.
← →
Nous Mellon © (2004-05-11 15:23) [14]
> Build группы из 14 немаленьких
А зачем столько?
← →
Игорь Шевченко © (2004-05-11 21:24) [15]
> LocalAlloc(LMEM_FIXED, Size) это просто сокращение для HeapAlloc(GetProcessHeap(),
> Size).
????????? Вообще-то LocalAlloc это вполне самостоятельная функция.
Страницы: 1 вся ветка
Текущий архив: 2004.05.30;
Скачать: CL | DM;
Память: 0.49 MB
Время: 0.04 c