Резиновый буфер

Тема в разделе "WASM.WIN32", создана пользователем calidus, 7 окт 2008.

  1. calidus

    calidus Member

    Публикаций:
    0
    Регистрация:
    27 дек 2005
    Сообщения:
    618
    значит первый цыкл будет

    Код (Text):
    1. invoke VirtualAlloc, AllocedMemory, availablData, MEM_COMMIT, PAGE_READWRITE
    а второй допустим

    Код (Text):
    1. invoke VirtualAlloc, AllocedMemory+размер в первом цыкле?, availablData, MEM_COMMIT, PAGE_READWRITE
    или второй цыкл опять но

    Код (Text):
    1. invoke VirtualAlloc, AllocedMemory, availablData+размер в первом цыкле?, MEM_COMMIT, PAGE_READWRITE
    =) млин я эту задачу переложил на систему как то , что что а это я даже не проверял
     
  2. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    Для этого:
    В общем получается, что MEM_RESERVE нужен только для организации своего менеджера памяти способного выделять/освобождать/перевыделять блоки памяти, а для "резинового" буфера достаточно MEM_COMMIT на максимальный размер и пусть система разруливает когда в этот блок реальную память подставлять.

    add:
    Не всё так просто как казалось...
     
  3. calidus

    calidus Member

    Публикаций:
    0
    Регистрация:
    27 дек 2005
    Сообщения:
    618
    =) Спасибо ... оказывается это и была проблема , чуть поменял код , все заработало шикарно.
     
  4. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Y_Mur
    Все таки MEM_RESERVE и MEM_COMMIT это не одно и то же. При резервировании создается только одна "манюсенькая" запись VAD (virtual address descriptor), а при передаче (commit) страниц, насколько я понимаю, создаются PDE\PTE на все переданные страницы - а это 4Кб на каждые 4Mб адресов
     
  5. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Мне вобщемто всёравно кто и что юзает, но если выделено много памяти(изначально я думал про гигобайты а не 20М), то вы вы все обламаетесь со NtAllocateX. У секции есть свойство - данные сохраняются при её освобождении. Тоесть если была создана секция размером в 1Г и в ней записаны данные, а затем проекция была освобождена эти данные не меняются. При обращении скажем к 20М этой секции проецируется только её часть, остальная часть остаётся выгруженной в своп. Итого памяти гиг, а проецируется мало. С обычной памятью такого вы не сможете сделоть.
     
  6. nester7

    nester7 New Member

    Публикаций:
    0
    Регистрация:
    5 дек 2003
    Сообщения:
    720
    Адрес:
    Russia
    Пока не обратишься, а так тоже "пометка" (если я тоже ща ничего не путаю).
     
  7. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    leo
    По наблюдению в диспетчере задач или процесс эксплорере выделение через MEM_COMMIT 1,3Гб приводит к расходу памяти < 500кб (что существенно меньше 1,3Мб согласно логике 4кб на 4Мб) точно померить сложно, поскольку эта величина соизмерима с "естественными колебаниями" памяти в системе ;)

    Но есть другие грабли - эта память реально резервируется и если запустить несколько приложений, которые захотят наCOMMITить даже неиспользумой памяти больше чем ОЗУ + файл подкачки, то винда затребует увеличения файла подкачки и "обломает" работу программ, которые ещё не успели захапать свой кусок памяти ;)
    Так что всё таки правильно не полагаться на виндовую "автоматику", а слушать дядьку Рихтера и резервировать через MEM_RESERVE с любым разумным запасом, а выделять через MEM_COMMIT только то что реально необходимо прямо сейчас.

    ЗЫ: Для CreateFileMapping всё тоже самое, только бесполезных параметров у функции больше + глюки в win 9x, оно конечно мелочь, но лучше когда прога по возможности мультивиндовая ;)
     
  8. calidus

    calidus Member

    Публикаций:
    0
    Регистрация:
    27 дек 2005
    Сообщения:
    618
    =) надо почитать рихтера. Когда читал набегом не запоминалось а вот когда в работе , другое дело.
     
  9. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    FileMapping с использованием файла подкачки так же как и VirtualAlloc с MEM_COMMIT сталкивается с ограничением: "суммарный размер MEM_COMMIT памяти всех приложений не должен превышать сумму ОЗУ + файл подкачки", однако обойти его можно, если использовать в каждой программе персональный временный файл подкачки. Однако этот файл реально создаётся на диске именно такого размера как указано в CreateFileMapping, и потому использовать это приём стоит только когда реально нужна большая память, а не в качестве "резинового буфера".

    Для автоматизации выделения памяти в зарезервированном (MEM_RESERVE) диапазоне адресов лучше воспользоваться советом Джеффри Рихтера - вызывать VirtualAlloc с MEM_COMMIT в SEH обрабатывающем ошибки доступа к ещё невыделенным страницам.
    Несколько неудобно, что для этого приходится обрабатывать EXCEPTION_ACCESS_VIOLATION, общее для всех ошибочных обращений к памяти, а не специальное для невыделенных страниц.

    В аттаче примеры обоих подходов.
     
  10. calidus

    calidus Member

    Публикаций:
    0
    Регистрация:
    27 дек 2005
    Сообщения:
    618
    Y_Mur Сэнкс , твои примеры оч классные )
     
  11. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    calidus
    О да, просто супер :lol: