malloc и фрагментация памяти

Тема в разделе "LANGS.C", создана пользователем Ss_oO0, 31 авг 2007.

  1. Ss_oO0

    Ss_oO0 New Member

    Публикаций:
    0
    Регистрация:
    11 ноя 2006
    Сообщения:
    65
    В Википедии прочитал:
    А я как раз в программе выделяю много маленьких кусочков памяти.
    Кто-нибудь сталкивался с невозможностью выделения доп. памяти из-за фрагментации? И если память освобождается и выделяется, к примеру равными порциями, то почему malloc не может выдавать первый подходящий по размеру кусок, который уже был выделен и освобожден?
    Чем вообще руководствоваться в этом отношении при разработке программ?
     
  2. censored

    censored New Member

    Публикаций:
    0
    Регистрация:
    5 июл 2005
    Сообщения:
    1.615
    Адрес:
    деревня "Анонимные Прокси"
    Иногда приходится писать свой менеджер памяти
     
  3. Ss_oO0

    Ss_oO0 New Member

    Публикаций:
    0
    Регистрация:
    11 ноя 2006
    Сообщения:
    65
    censored
    может мне еще свою ОС написать :)
    заточенную специально под свой malloc
     
  4. nester7

    nester7 New Member

    Публикаций:
    0
    Регистрация:
    5 дек 2003
    Сообщения:
    720
    Адрес:
    Russia
  5. AsmGuru62

    AsmGuru62 Member

    Публикаций:
    0
    Регистрация:
    12 сен 2002
    Сообщения:
    689
    Адрес:
    Toronto
    Используй нормальный HeapAlloc(), только для каждого сложного объекта надо иметь собственный хэндл (от HeapCreate()). Фрагментация резко уменьшится и код будет быстрее, потому что при уничтожении большого объекта не надо все его маленькие элементы удалять вызовом free() - вместо этого просто вызвать HeapDestroy().
     
  6. censored

    censored New Member

    Публикаций:
    0
    Регистрация:
    5 июл 2005
    Сообщения:
    1.615
    Адрес:
    деревня "Анонимные Прокси"
    Ss_oO0
    причем здесь ОС?
     
  7. nester7

    nester7 New Member

    Публикаций:
    0
    Регистрация:
    5 дек 2003
    Сообщения:
    720
    Адрес:
    Russia
    [deleted]
     
  8. crypto

    crypto Active Member

    Публикаций:
    0
    Регистрация:
    13 дек 2005
    Сообщения:
    2.533
    Ss_oO0
    Есть еще сборщики мусора GarbageCollector (к примеру, в Smalltalk, Python), они высвобождают память тех объектов, на которые отсутствуют ссылки (ReferenceNum=0).
     
  9. Agent666

    Agent666 New Member

    Публикаций:
    0
    Регистрация:
    19 июл 2007
    Сообщения:
    98
    Я сталкивался с этой проблемой, и могу сказать, что в общем случае она не имеет решения.
    Если твоей проге нужно использовать более 1гб памяти нарезаной мелкими кусками, и оптимизировать это никак нельзя, то тебя спасет только переход на x64 платформу (у которой больше адресной пространство). Ничто другое к сожалению помочь не в силах.
     
  10. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    Ss_oO0
    Лови: SmallObject allocator, как общую реализацию. А вообще, тебе придётся написать или взять готовый менеджер памяти для маленьких выделений памяти, т.к. глупо ждать эффективности в специфичных случаях от универсальных менеджеров (сишного или виндового).
     
  11. Ss_oO0

    Ss_oO0 New Member

    Публикаций:
    0
    Регистрация:
    11 ноя 2006
    Сообщения:
    65
    AsmGuru62
    Идею понял, но вряд ли смогу применить из-за необходимости контроля за множеством хэндлов. Существующая программа и так уже слишком сложная(инженерный пакет), и усложнять ее дальше - самоубийство.
    Agent666
    Вроде бы 32 бита адресуют до 4 Гб?
    censored
    Сорри, сначала не понял что такое менеджер памяти, потом погуглил и все стало ясно. Да, возможно придется его делать.

    Вообще, сложилось впечатление, что вопрос этот нетривиальный и к тому же алгоритмы выделения памяти разные на разных ОС. Однако изначально интересовал другой вопрос: сохраняет ли программа работоспособность при сильной фрагментации. (насколько она тормозит при этом - неважно).
    То есть более конкретно: допустим, у нас в распоряжении 1Гб памяти. Какое-то время программа работала, интенсивно выделяя и освобождая небольшие кусочки памяти. А потом в какой-то момент захотела выделить большой обьем памяти, но не больше суммарного свободного (оставшегося от 1Гб) объема. Может ли в каких-то случаях (на каких-то ОС?) это вызвать ошибку и невозможность выделения? Это принципиально, поскольку если такое возможно, то я буду вводить какие-то контролирующие процедуры, мониторинг памяти и т.п. Важна прежде всего надежность программы.
     
  12. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    А если написать менеджер кучи с поддержкой дефрагментации? Чтобы он выдавал не фиксированный адрес, а место, где он хранится, а сами блоки перемещались бы самостоятельно при освобождении какого-либо блока.
    Я хотел такое написать, тока запутался с чем-то и забросил
    В конце концов это и будет результатом. Суммарный объем свободной памяти будет достаточен для выделения блока, только вот ни одного свободного блока такой длины не найдется и выделение будет невозможно
     
  13. Ss_oO0

    Ss_oO0 New Member

    Публикаций:
    0
    Регистрация:
    11 ноя 2006
    Сообщения:
    65
    Great
    Идея интересная, но как ты себе это представляешь? Вместо:
    char *s;
    s = (char*)malloc(1000);
    s[0]='A';

    Нужно писать
    char **s;
    s = (char**)my_super_malloc(1000);
    (*s)[0]='A';

    Так что-ли?
     
  14. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Ну типа того.
    допустим под кучу выделено 100 страниц, из них первые 5 будут содержать структуры, хранящие в себе адрес блока, размер ну и флаг занятости, например. my_super_alloc будет возвращать адрес поля этой структуры, содержащего начало блока.
    а free кроме освобождения блока будет еще перемещать занятые блоки ближе друг к другу.

    Естественно, информация, которую можно записывать в такую кучу, не должна зависеть от положения в памяти, иначе перемещение блока плохо закончится для программы