BugDigger

Junior Member | Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору persicum Внутри у него 3 типа блоков: мелкие, средние и большие (размеры были в документации). "Большие" вроде по логике должен освобождать немедленно, остальные придерживает для будущего распределения (чтобы не нырять каждый раз в API, что долго), пока сумма придержанного ниже некоторого порога или просто число отложенных операций ниже порога (точно не знаю). Когда вы освобождаете 2 раза подряд, пороги, наверное, превышаются, и делается освобождение. Выпадать из-за нехватки памяти может не только из-за реальной нехватки, но и из-за фрагментации памяти, когда много мелких блоков отводятся и потом в случайном порядке освобождаются. В результате в сумме есть много свободной памяти, но она оказывается в виде мелких участков между занятыми. И когда вы пытаетесь выделить блок заметных размеров, можете получить отказ. Разные менеджеры памяти борются с этим с разной степенью успешности, FastMM в этом смысле вроде вполне на уровне. Когда вы освобождаете 2 смежных блока, образуется бОльшая свободная дырка, в которую может влезть очередной запрошенный блок. Есть еще одна засада с большими bmp (на 32 битах, на 64 я не работаю и потому не знаю) с PixelFormat=pfDevice, т.е. по умолчанию. Тут вступают в действие достаточно жесткие ограничения видеокарты (или драйвера, хз). И, между прочим, "безобидные" bmp.SaveToFile/LoadFromFile используют внутри себя pfDevice... |