![]() |
|
Модераторы: feodorv, GremlinProg, xvr, Fixin |
![]()
|
|
| rudolfninja |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 341 Регистрация: 19.2.2013 Где: г. Минск Репутация: 1 Всего: 6 |
Доброго времени суток. Пришлось столкнуться с функцией HeapWalk. Пример взял с msdn.
Вот, что вернула функция:
Кучу создавал так: _heap = HeapCreate(HEAP_GROWABLE, 0, 0); Потом выделил в ней 2 блока по 10 байт каждый. Затем вызвал HeapWalk. Насколько я знаю, раз в структуре PROCESS_HEAP_ENTRY установлен флаг PROCESS_HEAP_REGION, значит элемент находится в начале непрерывной области нераспределенной виртуальной памяти. На компе 32ГБ ОЗУ, то есть оперативаня память не могла закончиться, что б система полезла в виртуальную. Читал и Рихтера и Побегайло, не нашел там ответа на свой вопрос. Если не трудно, прокомментируйте, пожалуйста, то, что вернула функция HeapWalk. Хотелось бы понять, что это значит и почему именно так. Спасибо. Это сообщение отредактировал(а) rudolfninja - 23.9.2013, 23:15 |
|||
|
||||
| feodorv |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 9 Всего: 45 |
Интересно, зачем Вы задали флаг HEAP_GROWABLE, такого флага в описании функции HeapCreate не числится, это флаг для функции RtlCreateHeap.
А при чём здесь ОЗУ? У каждого процесса своё виртуальное адресное пространство, неким прозрачным образом отображаемое на ОЗУ или страничный файл. Процесс непосредственно с ОЗУ дела не имеет.
Первым делом в адресном пространстве процесса был зарезервирован регион (через VirtualAlloc) под нужды кучи, размером 262144 байт (262144 = 0x14060000 - 0x14020000 = 258048 + 4096). Вторым делом первая страница (4096 байт) этого региона передаётся процессу (теперь он может оттуда/туда читать/писать), остальное пространство блока остаётся недоступным для чтения/записи, но всё равно зарезервированным (никто другой эту область адресного пространства уже не сможет перезаказать). Часть переданной страницы адресного пространства ушло на управляющие структуры кучи (размером 1416 байт, 0x598 = 1432 байта, на что ушло ещё 16 байт, я не знаю). Тем не менее, первая аллокированная память пошла со смещением 2000 в регионе... Ну и потом собственно аллокированная память:
плюс оставшаяся незанятая непрерывная память в переданных страницах зарезервированного региона размером 2008+16 байт со смещением в регионе 2056 (0x1000 - 0x808 - 16 = 2008+16). -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
||||
|
|||||
| rudolfninja |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 341 Регистрация: 19.2.2013 Где: г. Минск Репутация: 1 Всего: 6 |
Так написано в книге Рихтера. То есть, получается, что под кучу выделается область виртуальной памяти, а потом, она передается ОЗУ? Это сообщение отредактировал(а) rudolfninja - 24.9.2013, 09:47 |
|||
|
||||
| feodorv |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 9 Всего: 45 |
Тут лучше Руссиновича почитать))) Эээ... Передаётся процессу, то есть страница адресного пространства процесса ассоциируется со страницей ОЗУ (или страничного файла), при этом переданная страница становится доступной на чтение/запись. Если страница просто зарезервирована (но не передана), то с ОЗУ она никак не связана. Механизм отображения страницы адресного пространства процесса на физическую память ОЗУ довольно затейлив, и целиком реализуется в режиме ядра. Пользовательский процесс может только попросить соответствующие подсистемы Windows передать (commit) память или высвободить (decommit) её. -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
|||
|
||||
| GremlinProg |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
В общем-то, это не так со времен создания AWE, которое позволяет "пользователю" мепировать физические страницы в виртуальные произвольным образом. Добавлено через 1 минуту и 27 секунд вернее - наоборот )) -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
|||
|
||||
| rudolfninja |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 341 Регистрация: 19.2.2013 Где: г. Минск Репутация: 1 Всего: 6 |
В общем, как я понял, память для кучи выделяется в виртуальном адресном пространстве процесса. При создании кучи (речь идет о пользовательской куче) в этом адресном пространстве (виртуальном) резервируется какой-то кусок памяти. Затем, при выделении памяти в куче, через HeapAlloc, часть зарезервированной области передается на физическую память, а остальная область просто остается зарезервированной и ждет, пока ее тоже будут использовать.
Если я все правильно понял, то возникает вопрос: чем куча отличается от виртуальной памяти (кроме того, что в куче меньшая гранулярность выделения памяти)? А если не прав - поправте, пожалуйста. |
|||
|
||||
| feodorv |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 9 Всего: 45 |
Ну, имелся в виду стандартный механизм управления памятью. И, по-моему, AWE недалеко от него ушёл))) Странный вопрос. Всё адресное пространство процесса - виртуальная память. Куча - это просто удобный механизм, позволяющий динамически её распределять. За простым на вид API спрятана серьёзная работа с памятью, работа, которую Вы при желании можете взять на себя, реализовав свою собственную кучу (правда, многие вызовы при этом всё равно будут использовать стандартную кучу процесса)))) Но даже так Вам придётся работать в виртуальном адресном пространстве процесса...
Одно из назначений кучи - оптимальное обращение с памятью, это да. Однако существуют реализации кучи, где каждый запрос на выделение памяти выполняется на новой странице адресного пространства процесса (что может привести к быстрому исчерпанию адресного пространства); такие кучи используются в отладочных целях. -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
|||
|
||||
| rudolfninja |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 341 Регистрация: 19.2.2013 Где: г. Минск Репутация: 1 Всего: 6 |
Вроде что-то прояснилось. Спасибо.
|
|||
|
||||
| GremlinProg |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
Само собой, если использовать только VirtualAlloc и VirtualFree (стандартный механизм управления памятью), то вклиниться в процесс "паджинга" не получится, как в сущности - в любой другой процесс, имеющий строгий API режима ядра. AWE как раз и позволяет создать свой механизм подкачки виртуальных страниц, т.к. управляет только процессом резервирования и отображения физических страниц. Где это может пригодиться? Ну, даже самое банальное - там, где заранее известно, к каким страницам будет обращаться приложение, т.е. там, где отлов обращений через исключение по PAGE_GUARD может играть какую-то роль в производительности ПО. Или в 32-битном приложении, которому требуется более 4Гб ОЗУ. ...если они (более 4Гб ОЗУ), конечно доступны физически )) -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
|||
|
||||
| feodorv |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 9 Всего: 45 |
AWE, без сомнения, механизм полезный. Но всё равно приходится резервировать регион памяти в адресном пространстве процесса (а я, в сущности, только об этом) путём VirtualAlloc, получается этакое memory mapped RAM (по аналогии с memory mapped file). Приятно иметь невыгружаемый набор страниц)))
Мда, памяти много не бывает))) -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
|||
|
||||
| GremlinProg |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
А вот только эта операция, пожалуй, и реализуется без какого-либо вмешательства "пользователем" в ядро, верно! Но это банальное резервирование диапазона страниц, без каких-либо дополнительных телодвижений, требующих подкачки или сброса страниц на диск. -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
|||
|
||||
![]()
|
| Правила форума "C/C++: Системное программирование и WinAPI" | |
|
|
На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы . Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |