invoke GetProcessHeap mov [GetProcessHeapMem],eax invoke HeapAlloc,[GetProcessHeapMem],0,$1aeaa0 cmp eax,0 je .errHeapAlloc mov [HeapAllocMem],eax invoke HeapFree,[GetProcessHeapMem],0,[HeapAllocMem] 1. Как более грамотно выделить память 2. Как грамотно завершить процессы с ней 3. Пусть мне нужно 1000 байт памяти... Как лучше поступать - выделять именно 1000 байт.... или прибавить один... или прибавить больше?? Как будет надёжнее??? Заранее благодарен за ответы...
Во первых - наконец то привет Васму По теме: если вам надо так мало памяти - то проще и достаточно взять из стэка.
Привет.. 1. Я про смысл - есть ли какой то смысл в том, чтобы выделять память с запасом, или это ни к чему. 2. А с каких величин стоит переходить от стека к выделению функцией?
Внесу свои 5 копеек Что оптимальнее из разных варантов (скорость), обсуждалось: http://web.archive.org/web/20020314161942/http://mastest.chat.ru/ http://www.gamedev.ru/code/forum/?id=42061 https://habrahabr.ru/post/158347/ http://f0dder.reteam.org/memalloc.htm Еще, GetProcessHeap можно реализовать руками, просто вставив код самого GetProcessHeap (на других виндах, по идее, тоже должно работать) MOV EAX,FS:[18h] MOV EAX,[EAX+30h] MOV EAX,[EAX+18h] Есть вопросы по heap'у. В интернетах говорится, что по умолчанию он имеет размер 1 мб для процесса, но карта памяти Олли показывает каждый раз разные небольшого размера куски.
rococo795, Выделение памяти напрямую через системные функции ― не самая удачная идея. Поэтому обычно в программе для управления памятью используют другой механизм: «кучу» (heap). Иногда термин «куча» употребляют как синоним термина «динамическая память». Куча (по определению) ― это название структуры данных, с помощью которой реализована динамически распределяемая память приложения. Так же термин «куча» употребляется когда ссылаются на вполне конкретный механизм (например: системную кучу процесса или любой другой менеджер памяти). Далее под кучей понимается динамическая память. Но не любая динамическая память ― куча. Память, выделяемую через VirtualAlloc(Ex), будем называть «динамической памятью», но не «кучей». А под «кучей» будем понимать дополнительный код по управлению памятью, реализованный «поверх» динамической памяти: так называемый «менеджер памяти» или «диспетчер кучи». Смысл кучи сводится к обработке множества запросов на создание/разрушение множества мелких объектов (блоков памяти). «Голая» динамическая память (черезVirtualAlloc(Ex)) крайне плохо приспособлена к этой задаче (из-за ограничений на кратность выделения и размера). Различные менеджеры памяти созданы для решения этой задачи. Менеджер памяти представлен функциями GetMem, FreeMem и ReallocMem. Использование GetMem и FreeMem похоже на использование VirtualAlloc и VirtualFree ― разница в меньшем объёме функций (память всегда выделяется только на чтение/запись) и в том, что память берётся не напрямую из системы, а из предварительно выделенной памяти. Также «кучей» называют не только сам механизм управления памятью, но и регион адресного пространства, выделенный для нужд кучи. Первоначально этот регион мал или вовсе отсутствует. По мере работы программы (и выделения в ней памяти) специальный диспетчер, управляющий кучами (менеджер памяти), будет расширять этот регион по мере необходимости или создавать новые регионы. А при освобождении блоков памяти в куче менеджер памяти будет возвращает системе соответствующие страницы физической памяти (по мере возможности). Куча весьма удобна при создании множества мелких блоков данных. Например, связанными списками и деревьями проще манипулировать, используя именно кучу, а не динамическую память. Преимущество кучи в том, что она позволяет вам игнорировать гранулярность выделения памяти и размер страниц и сосредоточиться непосредственно на своей задаче ― абстрагироваться от особенностей аппаратной части. А недостаток является прямым следствием преимущества: вы теряете прямой контроль над передачей физической памяти и её возвратом системе. Что касается скорости работы, то она сильно зависит от специфики данных. Как правило, менеджер памяти оптимизируется под типичные операции в программе и работа с ним наиболее оптимальна в большинстве случаев. С другой стороны, могут быть вырожденные случаи, когда накладные расходы на управление памяти в куче перевешивают выигрыш от экономии на вызовах ядра (вызов VirtualAlloc(Ex) означает обращение к режиму ядра, а переключение контекстов (пользовательский режим → режим ядра и обратно) ― не самая быстрая операция). Стандартный менеджер памяти ― это не единственный диспетчер кучи в вашей программе. Вам также доступны: HeapAlloc/HeapFree LocalAlloc/LocalFree GlobalAlloc/GlobalFree IMalloc.Alloc/IMalloc.Free CoTaskMemAlloc/CoTaskMemFree SHAlloc/SHFree Чем они отличаются? Это разные реализации одной идеи. В системе есть несколько менеджеров памяти, которые имеют разные цели и используются в разных случаях. Вышеуказанные функции ― это точки доступа к различным менеджерам памяти. Когда их надо использовать? Когда вам нужно «поговорить» с кодом, который понимает только их. К примеру, буфер обмена Windows работает с GlobalAlloc/GlobalFree. Самое главное, нужно помнить правило: «кто девушку ужинает ― тот ее и танцует». Иными словами, если память выделили через GetMem ― то освобождать ее должны через FreeMem, выделили через VirtualAlloc ― освобождать нужно через VirtualFree, через LocalAlloc ― тогда LocalFree... взято из Адресное пространство под микроскопом
Во-первых, виртуальная, а не динамическая же, ну. Во-вторых, она вообще никак не приспособлена для этой задачи. Virtual-функции - это низкоуровневый способ управления памятью, используемый самой системой и он оперирует целыми страницами памяти. Использовать их в высокоуровневых приложениях, это как читать файлы через порты ввода/вывода, вместо использования CreateFile()/ReadFile().
Система не поддерживает расширение буфера, только в частном случае - стека и вниз. Поэтому часто приходится выделять больший размер буфера , с запасом и затем освобождать не используемую его часть. Это позволяет сделать аллокатор хипа. Кернел аллокатор работает со страничной гранулярностью, поэтому нельзя освободить не используемую часть страничного буфера - при большом числе буферов память будет не эффективно использоваться. Такой аллокатор юзается для спец целей, когда обычный не может быть использован, например при низкоуровневой работе(возможны деадлоки из за рекурсивных вызовов аллокатора реализованного в юм) или манипуляция доступом к памяти.
Indy_ Спасибо.... Не буду умничать... Не всё понятно пока что... Но спасибо!!! А вдруг пригодиться через месяц другой...
Чем ты тут занимаешься вообще? На старом васме одной из последних тем было про виртуальную память и отличие Virtual* функций от Heap*. Страниц на 10 там разжевали все
Да хорош шутить..... Всё... ! Да занимаюсь всякой уйней... и редко... Эт я активность изображаю, чтоб форум чуть подоживить.... Но чё то не особо оное идёт... И главное никто не обращается с реальными вопросами-проблемами, которые сиюминутно появляются в работе.. Либо все очень умные стали - либо не знаю.... (Не думаю что все стали умны и стали грамотно писАть.... почти везде небось найдётся что умного подсказать... не нет! всё у всех нормуль.... только чем дальше - тем глючных прог всё больше и больше..... ) Сидю... На медленно падающий снег в свете фонарей смотрю.... Таинство мироздания....
все освоили гугл)) впрочем непонимающим и он не помогает вот поднимется новый адрес форума в поиске и понабегут студенты в тему для начинающих