GetProcessHeap() => куча 1Мб?

Тема в разделе "WASM.WIN32", создана пользователем AlannY, 9 дек 2008.

  1. AlannY

    AlannY New Member

    Публикаций:
    0
    Регистрация:
    24 окт 2008
    Сообщения:
    41
    Прочитал в книжке г-на Юрова по ассемблеру, что у программы есть стандартная куча, хэндл которой возвращается при GetProcessHeap().

    Теперь вопрос: правда ли что размер этой кучи всего, как пишет Юров, 1Мб? А для создания кучи большего размера нужно вызывать HeapCreate?

    Читал в MSDN, так там ничего толком на эту тему не написано: только как функции вызывать :-(
     
  2. xorrax

    xorrax New Member

    Публикаций:
    0
    Регистрация:
    6 ноя 2008
    Сообщения:
    11
    Дж. Рихтер, глава "Динамически распределяемая память".
     
  3. AlannY

    AlannY New Member

    Публикаций:
    0
    Регистрация:
    24 окт 2008
    Сообщения:
    41
    А если вкратце?
     
  4. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Вкратце: главная (стандартная) куча процесса создается по умолчанию с dwInitialSize=1Мб и dwMaximumSize=0, т.е. явлется растущей - если не хватит 1Мб, то будет выделен еще 1Мб и т.д.
    PS: На размер и рост кучи влияют только блоки размером < ~512К, т.к. большие блоки выделяются не в самой куче, а отдельно через VirtualAlloc и в куче хранится только список этих блоков
     
  5. AlannY

    AlannY New Member

    Публикаций:
    0
    Регистрация:
    24 окт 2008
    Сообщения:
    41
    Т.е. мне не нужно заботиться о том, что кончится память в кучи? она будет расширена автоматически?
     
  6. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Да
     
  7. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    тогда возникает вопрос если не нужно заботится о том что закончится память в куче
    то почему бы все время не использовать только кучу, зачем тогда всякие VirtualAlloc юзаем? )
     
  8. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    Asterix
    Во первых зачем лишний переходник - если всё равно к VirtualAlloc обратится, а во вторых:
    http://www.wasm.ru/forum/viewtopic.php?id=29372
    http://www.wasm.ru/forum/viewtopic.php?id=29115&p=2
     
  9. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Всё имеет и плюсы и минусы. Операция выделения памяти из кучи быстра, это может быть критично для маленьких блоков с очень частым уничтожением, выделением. Но и недостатки у кучи есть, та же фрагментация.
     
  10. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Asterix
    Ежели по простому MEM_COMMIT+PAGE_READWRITE, то во-первых, по привычке, традиции, "слышал звон.." и т.п., т.к. в win9x в куче можно было выделить максимум 4Мб, во-вторых, "так круче", "зачем лишний переходник" и т.п.
    Ну а ежели по "спецназначению", то сам бог велел, т.к. VirtualAlloc обеспечивает кучу доп.возможностей: резервирование + commit\decommit любого числа страниц с протектом в одном флаконе, возможность выделения по верхним адресам и по заданному адресу. Вот только обрезка резерва почему-то не предусмотрена, к великому сожалению..
     
  11. dgs

    dgs New Member

    Публикаций:
    0
    Регистрация:
    23 июн 2008
    Сообщения:
    434
    А если через HeapCreate, то аналогично?
     
  12. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    dgs
    в HeapCreate ты сам укажешь мин/мах размеры. если max=0 то будет расти сколько нужно, если не 0 то только до max.
     
  13. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    dgs
    Читаем мсдн: если dwMaximumSize=0, то аналогично.
    Иначе сразу два ограничения - нельзя выделять блоки размером более 512К и суммарный размер выделенных блоков (с учетом оверхедов) не может превышать dwMaximumSize (округленной вверх на 64К)
     
  14. dgs

    dgs New Member

    Публикаций:
    0
    Регистрация:
    23 июн 2008
    Сообщения:
    434
    Вот это я лохманулся... :dntknw:
     
  15. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Поясню почему в нерастущей куче нельзя выделять большие блоки несмотря на большой размер dwMaximumSize:
    Ограничение в 512К связано со структурой заголовка блока - размер хранится в 8-байтовых единицах в поле word, откуда имеем max < 65536*8 = 512К. Если куча растущая (dwMaximumSize=0), то блоки >= 512К выделяются отдельно (т.е. суммарный размер кучи растет), если не растущая, то - получаем облом несмотря на dwMaximumSize, т.к. в самой куче в (пределах dwMaximumSize) выделить большой блок невозможно, а выделить отдельно "нельзя по определению", т.к. при этом суммарный размер станет > dwMaximumSize
     
  16. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    leo
    А где сейчас хранится связанный список блоков? отдельно со ссылками на блоки ли как в ДОС каждому блоку приписывается заголовок?
     
  17. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    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
     
  18. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    leo
    спасибо ;)
    круто наворочено ;) не ожидал такого однако :))
     
  19. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Дык это вроде стандартный приемчик, и в бормановской куче такая же табличка юзается, только побольше - до 4К