
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[216.73.216.52] |
![]() |
|
Страницы: (2) [1] 2 все ( Перейти к последнему сообщению ) |
![]() |
|
|
Люди, подскажите плиз!!!!
Както можно при старте программы выделить 1гиг памяти под разные процедуры, чтобы они были зарезервированы только для нее....? Ну и конечно потом их освободить.... Спасибки! |
Сообщ.
#2
,
|
|
|
Зачем?
В процессе работы она что, сама не может брать, сколько захочет? |
Сообщ.
#3
,
|
|
|
Смущает фраза "чтобы они были зарезервированы только для неё". Речь идёт о физической памяти? А если столько нету?
|
Сообщ.
#4
,
|
|
|
речь идетъ о большом количестве из кучи..... а када сама берет то происходит фрагментация кучи..... а это еще + время!!!!! а нада сразу ... и на фрагментацию время не уходит, проверил!!!!!!!
|
Сообщ.
#5
,
|
|
|
Цитата zhuravlev @ а када сама берет то происходит фрагментация кучи Ок, для работы программа берёт память: 1). Выделяется менеджером памяти (из кучи). 2). Как-то выделяется руками из заранее подготовленного участка. Я не вижу разницы между этими двумя случаями. Какое-такое принципиальное отличие во втором случае, что вы прямо уверены, что там не будет фрагментации? Цитата zhuravlev @ большом количестве из кучи..... Большом количестве чего? Здесь нет телепатов. Цитата zhuravlev @ и на фрагментацию время не уходит, проверил!!!!!!! Ну-ка, поделитесь с общественностью, как это вы проверили? |
Сообщ.
#6
,
|
|
|
Зачем нам куча? Просто выделяем виртуальную память через функцию VirtualAlloс. Гранулярность 64 КБ. Никакой фрагментации и другого бреда .....
![]() ![]() ![]() procedure TForm1.Button1Click(Sender: TObject); var P:pointer; size:DWORD; begin Size:=700*1024*1024; //700 метров p:=VirtualAlloc(0,size,MEM_COMMIT+MEM_RESERVE,PAGE_READWRITE); if p=nil then showmessage('ERROR'); end; вот только зачем это? Можно выделить до 2 ГБ памяти, но только есть ограничения. Не помню точно какие, но одно точно помню (в Win32) : объём памяти выделенный всеми процессами в сумме, не должен превышать 4 ГБ (т.е. чтобы размер файла подкачки не превышал 4 ГБ). |
Сообщ.
#7
,
|
|
|
Ahilles
Пасиб .... попробую!!!! |
Сообщ.
#8
,
|
|
|
Цитата Ahilles @ Не помню точно какие, но одно точно помню (в Win32) : объём памяти выделенный всеми процессами в сумме, не должен превышать 4 ГБ (т.е. чтобы размер файла подкачки не превышал 4 ГБ). С чего вы это взяли? Нет таких ограничений. Для начала - суммарная виртуальная память это всё же RAM + pagefile, а не просто pagefile. Кроме того, в конце-концов есть же AWE. Или вы про это? Кстати, при желании можно и в обычном пользовательском режиме 3Gb использовать: Summary of the recent spate of /3GB articles. Цитата Ahilles @ Просто выделяем виртуальную память через функцию VirtualAlloс Чем это отличается от GetMem(P, 700*1024*1024); или SetLength(S, 700*1024*1024)? Проблема с фрагментацией как была, так и осталась. |
Сообщ.
#9
,
|
|
|
А что, собственно, за проблемы с фрагментацией?
Если мы работаем в защищенном режиме, то мы всегда работатем через таблицу страниц и процессор на аппаратном уровне производит трансляцию адресов, поэтому на уровне прикладной задачи память непрерывна, а если физически она расположена в разных частях, то на скорости доступа это никак не сказывается. Если же мы работаем в реальном режиме... А что, кто-то еще работает в реальном режиме? |
Сообщ.
#10
,
|
|
|
Цитата andriano @ А что, собственно, за проблемы с фрагментацией? Речь идёт не о фрагментации физической памяти, а о фрагментации адресного пространства процесса. Представьте, что вы выделили 2 гига памяти кусками по 1 Mb. Теперь вы освобождаете каждый нечётный кусок. Получается, что вы освободили 1 Gb памяти, и занято у вас тоже 1 Gb (т.е. 50/50). Причём карта памяти похожа на решето - куски занятой памяти равномерно перемешаны с кусками свободной памяти. А теперь вы хотите выделить 2 Mb памяти. Несмотря на то, что суммарно у вас ещё есть целый 1 Gb свободной памяти, вы не можете это сделать, т.к. максимальный размер непрерывного свободного участка у вас = 1 Mb. Зато у вас 1024 таких участка ![]() Это и есть фрагментация. Суть её в том, что из-за интернисвного цикла выделения/освобождения памяти адресное пространство процесса всё больше начинает напоминать решето. Именно по этой причине практически невозможно использовать в программе максимум памяти, доступной режиму пользователя - всегда будут зазоры. При этом нет разницы, выделяет ли вам память ОС, менеджер памяти или вы выделяете их из зарезервированного участка памяти, как это хочет сделать автор вопроса. Разница может быть только в алгоритме выделения. Не имеет значения место выделения. Имеет значение как, в какой последовательности вы работаете с памятью. Например, в отличие от менеджера памяти старых Delphi, менеджер памяти в новых Delphi (FastMM) группирует данные по размеру: мелкие - с мелкими, средние - со средними, а для крупных он вообще вроде запрашивает у ОС отдельные блоки памяти. Это способствует уменьшению фрагментации памяти. Другой пример - нет необходимости выделять память под каждый из кучи однотипных объектов. Лучше загнать их в массив. Ещё пример? Что ж, например, в XP и выше есть куча с низкой фрагментацией. Потом. В нашем же примере - если бы мы заранее сперва выделили память для всех чётных кусков, а затем - для нечётных, то после освобождения памяти у нас получилось бы начало адресного пространства - один целый блок занятой памяти в 1 Gb, а вторая половина - один свободный блок памяти в 1 Gb. Т.е. 0% фрагментации. |
Сообщ.
#11
,
|
|
|
CodeMonkey, спасибо за объяснение. Искренне надеюсь, что оно чем-то поможет zhuravlev, создавшему эту тему.
Что же касается моего вопроса, то сформулированная Вами проблема никак не связана с тем вопросом, что задал zhuravlev (о чем Вы, собственно, и пишите в 4 абзаце). Собственно, фрагментация возникает из-за частых и бездумных запросов к менеджеру памяти, с чем последний, даже самый совершенный, справиться, естественно, не может. Поэтому бороться следует не с симптомами, а с самой болезнью, - т.е. осмыслить политику запросов и освобождения памяти в собственной программе. |
Сообщ.
#12
,
|
|
|
Цитата Ahilles @ объём памяти выделенный всеми процессами в сумме, не должен превышать 4 ГБ (т.е. чтобы размер файла подкачки не превышал 4 ГБ). да, да, да забыл. это ещё не считая промэпированную память. но там ещё есть ограничения.... в книге Руссиновича и Соломна всё подробно об этом написано, не помню точно. Цитата CodeMonkey @ Для начала - суммарная виртуальная память это всё же RAM + pagefile, а не просто pagefile нет, но суммарная виртуальная память это только pagefile, потому что "а вдруг придётся выгрузить всю память в своп", хотя в режиме ядра есть ещё и невыгружаемая память. Вернее даже если физической памяти хватает, файл подкачки всё равно будет занимать место, но при этом он не будет использоваться. Например, у меня XP 1 Гиг памяти, её хватате и избытком, всё приложения сейчас в сумме расходуют примерно 400 метров, но файл подкачки имеет размер 512 метром, но при этом почти не используется (в настройках файл подкачки 512-2048). И когда гооврят что файл подкачки должен иметь размер не меньше, чем размер физической памяти, исходят из утверждения "а вдруг придётся выгрузить всю память в своп". опять же, в книге Руссиновича и Соломна всё подробно об этом написано, не помню точно. Цитата CodeMonkey @ Чем это отличается от GetMem(P, 700*1024*1024); или SetLength (S, 700*1024*1024)? Проблема с фрагментацией как была, так и осталась. А как ты объяснишь что гранулярность у них 8 байт, в то время как у VirtualAlloc 64КБ? Функции GetMem и SetLength работают с кучей а не с виртуальнйо памятью, и они вызывают функции HeapAlloc. Цитата CodeMonkey @ Кроме того, в конце-концов есть же AWE. нет, это уже другая история, и толк от AWE есть только тогда когда ядро винды PAE и размер физической памяти больше чем размер виртуальной памяти, т.е. когда физическая память больше чем 2 ГБ. А по поводу менеджера куч Delphi, то там разработчики сделали так: в начале выделяется большой кусок памяти под кучу, и функции GetMem и SetLength это аналоги функции HeapAlloc, т.е. выделяют память вручную из кучи. Не понимаю зачем они так сделали когда можно воспользоваться теми функциями, которые предоставляет сама система. |
Сообщ.
#13
,
|
|
|
Цитата Ahilles @ А как ты объяснишь что гранулярность у них 8 байт, в то время как у VirtualAlloc 64КБ? Да нет, это понятно. В смысле: понятно, чем VirtualAlloc отличается от менеджера памяти Delphi. Я про то, что нет разницы где брать память. Важно - как её использовать. Цитата Ahilles @ нет, но суммарная виртуальная память это только pagefile Цитата Ahilles @ нет, это уже ругая история Это всё тоже понятно. Я это к тому, что не стоит говорить Цитата Ahilles @ , т.к. это неверно. объём памяти выделенный всеми процессами в сумме, не должен превышать 4 ГБ |
Сообщ.
#14
,
|
|
|
Цитата Ahilles @ А по поводу менеджера куч Delphi, то там разработчики сделали так: в начале выделяется большой кусок памяти под кучу, и функции GetMem и SetLength это аналоги функции HeapAlloc, т.е. выделяют память вручную из кучи. Не понимаю зачем они так сделали когда можно воспользоваться теми функциями, которые предоставляет сама система Во-первых, "так делают" любые менеджеры кучи, в т.ч. и виндовые HeapAlloc\HeapFree. Во-вторых, АПИ содержит немало функций, которые по большому счету не являются системными (например, функции работы со строками) и приложение может по своему усмотрению использовать их или нет. В частности борландовский менеджер специально заточен на быстрое выделение и уничтожение небольших блоков памяти под строки и экземпляры VCL-объектов - классический борландовский менеджер работает в 2-3 раза быстрее виндового в однопоточных приложениях без ShareMem, а FastMM даже с ShareMem вдвое быстрее, а без до 6-7 раз (см.тестовый код и примерные цифры) |
Сообщ.
#15
,
|
|
|
Цитата leo @ классический борландовский менеджер работает в 2-3 раза быстрее виндового в однопоточных приложениях без ShareMem, а FastMM даже с ShareMem вдвое быстрее, а без до 6-7 раз (см.тестовый код и примерные цифры) я так и думал. именно это мне и нужно было. Добавлено Цитата CodeMonkey @ т.к. это неверно. да, я был не прав. У меня PAE ядро и 1 гиг памяти, у меня получилось 6 раз (в разных приложениях) выделить 900 метров памяти, в результате чего суммарный размер всех файлов подкачки был примерно 5,5 ГБ. Кстати, в одном приложении у меня так и не получилось выделить 1000 мегабайт памяти, пришлось запустить 6 копий и выделить в каждой по 900 метров (программы представляли собой форму с одной кнопкой). Всё таки какие-то ограничения есть... |