Прочитал в книжке г-на Юрова по ассемблеру, что у программы есть стандартная куча, хэндл которой возвращается при GetProcessHeap(). Теперь вопрос: правда ли что размер этой кучи всего, как пишет Юров, 1Мб? А для создания кучи большего размера нужно вызывать HeapCreate? Читал в MSDN, так там ничего толком на эту тему не написано: только как функции вызывать :-(
Вкратце: главная (стандартная) куча процесса создается по умолчанию с dwInitialSize=1Мб и dwMaximumSize=0, т.е. явлется растущей - если не хватит 1Мб, то будет выделен еще 1Мб и т.д. PS: На размер и рост кучи влияют только блоки размером < ~512К, т.к. большие блоки выделяются не в самой куче, а отдельно через VirtualAlloc и в куче хранится только список этих блоков
тогда возникает вопрос если не нужно заботится о том что закончится память в куче то почему бы все время не использовать только кучу, зачем тогда всякие VirtualAlloc юзаем? )
Asterix Во первых зачем лишний переходник - если всё равно к VirtualAlloc обратится, а во вторых: http://www.wasm.ru/forum/viewtopic.php?id=29372 http://www.wasm.ru/forum/viewtopic.php?id=29115&p=2
Всё имеет и плюсы и минусы. Операция выделения памяти из кучи быстра, это может быть критично для маленьких блоков с очень частым уничтожением, выделением. Но и недостатки у кучи есть, та же фрагментация.
Asterix Ежели по простому MEM_COMMIT+PAGE_READWRITE, то во-первых, по привычке, традиции, "слышал звон.." и т.п., т.к. в win9x в куче можно было выделить максимум 4Мб, во-вторых, "так круче", "зачем лишний переходник" и т.п. Ну а ежели по "спецназначению", то сам бог велел, т.к. VirtualAlloc обеспечивает кучу доп.возможностей: резервирование + commit\decommit любого числа страниц с протектом в одном флаконе, возможность выделения по верхним адресам и по заданному адресу. Вот только обрезка резерва почему-то не предусмотрена, к великому сожалению..
dgs в HeapCreate ты сам укажешь мин/мах размеры. если max=0 то будет расти сколько нужно, если не 0 то только до max.
dgs Читаем мсдн: если dwMaximumSize=0, то аналогично. Иначе сразу два ограничения - нельзя выделять блоки размером более 512К и суммарный размер выделенных блоков (с учетом оверхедов) не может превышать dwMaximumSize (округленной вверх на 64К)
Поясню почему в нерастущей куче нельзя выделять большие блоки несмотря на большой размер dwMaximumSize: Ограничение в 512К связано со структурой заголовка блока - размер хранится в 8-байтовых единицах в поле word, откуда имеем max < 65536*8 = 512К. Если куча растущая (dwMaximumSize=0), то блоки >= 512К выделяются отдельно (т.е. суммарный размер кучи растет), если не растущая, то - получаем облом несмотря на dwMaximumSize, т.к. в самой куче в (пределах dwMaximumSize) выделить большой блок невозможно, а выделить отдельно "нельзя по определению", т.к. при этом суммарный размер станет > dwMaximumSize
leo А где сейчас хранится связанный список блоков? отдельно со ссылками на блоки ли как в ДОС каждому блоку приписывается заголовок?
Y_Mur Насчет ДОС и low fragmentation heap не знаю, а в стандартной виндовой куче ес-но каждому блоку приписывается заголовок - занятому 8-байтный _HEAP_ENTRY, свободному плюс еще 8 байт на двусвязный FreeList. Ссылки на списки свободных блоков хранятся в заголовке кучи в таблице _HEAP.FreeLists[128] - по индексу i=0 ссылка на список блоков размером более 1К, по остальным на списки размером i*8. Для виртуальных блоков размером более 512К есть свой список _HEAP.VirtualAllocdBlocks. PS: Однако по всей видимости мелкософты заложили возможность изменения работы стандартной кучи путем примочки под названием FrontEndHeap или front end allocator, который для стандартной кучи (видимо) ничего не делает и перенаправляет вызовы к back end allocator-у, основанному на FreeLists
Дык это вроде стандартный приемчик, и в бормановской куче такая же табличка юзается, только побольше - до 4К