Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 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.51 MB
Время: 0.043 c
11-1074625930
Ertong
2004-01-20 22:12
2004.05.30
BitBtn глюкавит


14-1083952838
Blackman
2004-05-07 22:00
2004.05.30
Стишок на ночь


6-1081426907
Makhanev A.S.
2004-04-08 16:21
2004.05.30
Блокирующие Сокеты: можно ли так делать...


3-1084046913
ser_ega
2004-05-09 00:08
2004.05.30
Database Desktop


6-1081921669
smily
2004-04-14 09:47
2004.05.30
Как узнать имя пользователя?