Хочу к примеру взять кусок памяти. Можно ли заранее узнать, сколько максимальноо можно брать, чтобы не было ошибки?
Да это понятно. Я и спрашиваю, можно ли как-то узнать, сколько я могу получить, прежде чем вызывать GlobalAlloc
Ну если уж на то пошло, то, согласно "плоской" модели памяти, проге может быть выделено до 2 ГБ (минус образ проги) виртуальной памяти, вне зависимости от размера физической RAM. Верхние 2 ГБ (по крайней мере в 98-м, с которым пока что необходимо, имхо, обеспечивать совместимость) система забирает себе.
Возьми, скажем, 2 ГБ. Если не возьмётся - уменьши количество беруемой памяти в два раза и попробуй ещё раз. И так далее. Совсем немного попыток понадобится.
Собственно GlobalAlloc выделяет память из кучи. И зависит сколько памяти выделилось для процессной кучи. Обычно это не так много.
n0name Во-первых, главная куча процесса является растущей (приращение идет сегментами по 1Мб). Во-вторых, блоки размером более 512К по любому выделяются не непосредственно в "общей куче", а "индивидуально" через VirtualAlloc и в куче сохраняются только ссылки (дескрипторы) на эти блоки TOLSTOPUZ Память в винде является виртуальной, поэтому (при достаточном свободном месте на диске) выделение блока ограничено только наличием подходящей "дыры" незанятых виртуальных адресов. Для поиска "дыры" нужно пробежаться по списку занятых адресов, что собственно и делает VirtualAlloc - если находит, то сразу и резервирует\выделяет. А бегать по списку только ради спортивного интереса без выделения памяти смысла нет, поэтому и апишки такой нет
по теме: GlobalMemoryStatus - от неё можно плясать. + фрагментированность АП, как уже сказали, не даст заполучить всю доступную вирт.память в один заход одним куском.
Угу. забыл про то что она growable. а разве не на ALIGN_UP(Size + sizeof(HEAP_HEADER), 16) ? Вот в это почему то не верю. Можешь ткнуть носом в дизасм листинг, сам я что-то не вижу...
Я имел ввиду не выделение блока внутри кучи, а о резервировании адресов под новый сегмент (HEAP.SegmentReserve = hHeap+18h = 1Мб по дефолту) В листинге без стакана не разберешься, поэтому лучше глянь в руководство по SoftIce и в структуры HEAP_ENTRY и HEAP Размер блока кучи измеряется в 8 байтных единицах и хранится в заголовке HEAP_ENTRY в виде ushort Size, отсюда и предельный размер бока, выделяемого в самой куче = 64К*8 = 512К. Реально предел берется чуть меньше (0FE00h*8 = 7F000h) и хранится в хидере самой кучи HEAP.VirtualMemoryThreshold (hHeap+14h). Ссылки на выделенные виртуальные блоки хранятся в списке Heap.VirtualAllocdBlocks (hHeap+50h) Что касается листинга, то в XP SP2 проверка на предельный размер выглядит так Код (Text): ;ntdll.RtlAllocateHeap 7C9116BF 3B7B 14 CMP EDI,[EBX+14] ;edi = (size+7) shr 3, ebx = hHeap 7C9116C2 ^ 0F86 F0FCFFFF JBE ntdll.7C9113B8 Дальше по джампу дебри непролазные (по кр.мере на первый взгляд), копаться в которых у меня желания не было и нет
leo а, ты про RtlAllocateHeap, я думал ты про GlobalAlloc говорли ибо ""индивидуально" через VirtualAlloc и в куче сохраняются только ссылки (дескрипторы) на эти блоки" думал что относится к однйо функции. В RtlAllocateHeap вполне возможно. Там кода - без поллитры не разобратся %)
n0name Я ж сказал "по любому выделяются", имея в виду, что GlobalAlloc в плане выделения памяти ничем не отличается от HeapAlloc -> RtlAllocateHeap. При GMEM_FIXED вообще сразу переходит на HeapAlloc, а для GMEM_MOVEABLE только доп.запись дискриптора в свой табличке создает и все. Поэтому и смысла в ней никакого нет, только для клипборда и дде для совместимости
Значит, практически с помощью кода можно получить максимально возможную квоту вплоть до 1 байта? Можно? И если да, то тогда насколько статичен будет этот полученный размер? Например, возьмёт и изменится, добавит пару байт... Вот в чём вопрос?
Какая пара байт ?! Если речь о 512К и более, то рулит VirtualAlloc с дискретом резервирования адресов = 64К ??? Насколько в проге (в экзешнике и всех длл) не будет явных или скрытых выделений или освобождений динамической памяти (включая Create\ExitThread, Load\FreeLibrary и т.п.)
Короче говоря, объясню, к чему я клоню... можно ли рассматривать некоторые моменты оперативной памяти как структуру настолько нестабильную, что есть возможность получать из некоторых её параметров "случайное число"?
TOLSTOPUZ Посмотри в Олли карту памяти любого приложения : если там и есть нестабильность, то довольно закономерная. Физ. память действительно делится между приложениями, но реальные адреса запрятаны в системе и без ring0 ты туда не попадешь.