В Википедии прочитал: А я как раз в программе выделяю много маленьких кусочков памяти. Кто-нибудь сталкивался с невозможностью выделения доп. памяти из-за фрагментации? И если память освобождается и выделяется, к примеру равными порциями, то почему malloc не может выдавать первый подходящий по размеру кусок, который уже был выделен и освобожден? Чем вообще руководствоваться в этом отношении при разработке программ?
Используй нормальный HeapAlloc(), только для каждого сложного объекта надо иметь собственный хэндл (от HeapCreate()). Фрагментация резко уменьшится и код будет быстрее, потому что при уничтожении большого объекта не надо все его маленькие элементы удалять вызовом free() - вместо этого просто вызвать HeapDestroy().
Ss_oO0 Есть еще сборщики мусора GarbageCollector (к примеру, в Smalltalk, Python), они высвобождают память тех объектов, на которые отсутствуют ссылки (ReferenceNum=0).
Я сталкивался с этой проблемой, и могу сказать, что в общем случае она не имеет решения. Если твоей проге нужно использовать более 1гб памяти нарезаной мелкими кусками, и оптимизировать это никак нельзя, то тебя спасет только переход на x64 платформу (у которой больше адресной пространство). Ничто другое к сожалению помочь не в силах.
Ss_oO0 Лови: SmallObject allocator, как общую реализацию. А вообще, тебе придётся написать или взять готовый менеджер памяти для маленьких выделений памяти, т.к. глупо ждать эффективности в специфичных случаях от универсальных менеджеров (сишного или виндового).
AsmGuru62 Идею понял, но вряд ли смогу применить из-за необходимости контроля за множеством хэндлов. Существующая программа и так уже слишком сложная(инженерный пакет), и усложнять ее дальше - самоубийство. Agent666 Вроде бы 32 бита адресуют до 4 Гб? censored Сорри, сначала не понял что такое менеджер памяти, потом погуглил и все стало ясно. Да, возможно придется его делать. Вообще, сложилось впечатление, что вопрос этот нетривиальный и к тому же алгоритмы выделения памяти разные на разных ОС. Однако изначально интересовал другой вопрос: сохраняет ли программа работоспособность при сильной фрагментации. (насколько она тормозит при этом - неважно). То есть более конкретно: допустим, у нас в распоряжении 1Гб памяти. Какое-то время программа работала, интенсивно выделяя и освобождая небольшие кусочки памяти. А потом в какой-то момент захотела выделить большой обьем памяти, но не больше суммарного свободного (оставшегося от 1Гб) объема. Может ли в каких-то случаях (на каких-то ОС?) это вызвать ошибку и невозможность выделения? Это принципиально, поскольку если такое возможно, то я буду вводить какие-то контролирующие процедуры, мониторинг памяти и т.п. Важна прежде всего надежность программы.
А если написать менеджер кучи с поддержкой дефрагментации? Чтобы он выдавал не фиксированный адрес, а место, где он хранится, а сами блоки перемещались бы самостоятельно при освобождении какого-либо блока. Я хотел такое написать, тока запутался с чем-то и забросил В конце концов это и будет результатом. Суммарный объем свободной памяти будет достаточен для выделения блока, только вот ни одного свободного блока такой длины не найдется и выделение будет невозможно
Great Идея интересная, но как ты себе это представляешь? Вместо: char *s; s = (char*)malloc(1000); s[0]='A'; Нужно писать char **s; s = (char**)my_super_malloc(1000); (*s)[0]='A'; Так что-ли?
Ну типа того. допустим под кучу выделено 100 страниц, из них первые 5 будут содержать структуры, хранящие в себе адрес блока, размер ну и флаг занятости, например. my_super_alloc будет возвращать адрес поля этой структуры, содержащего начало блока. а free кроме освобождения блока будет еще перемещать занятые блоки ближе друг к другу. Естественно, информация, которую можно записывать в такую кучу, не должна зависеть от положения в памяти, иначе перемещение блока плохо закончится для программы