В чем разница между VirtualAlloc и HeapAlloc?



существует множество способов выделения памяти в среде Windows, таких как VirtualAlloc,HeapAlloc,malloc,new.



Итак, в чем же разница между ними?

861   6  

6 ответов:

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

VirtualAlloc

низкоуровневый, Windows API, который предоставляет множество опций, но в основном полезен для людей в довольно специфических ситуациях. Может выделять память только в больших кусках (edit: not 4KB). Бывают ситуации, когда вам это нужно, но вы будете знать, когда вы находитесь в одной из этих ситуаций. Один из самых обычно, если вам нужно поделиться памятью непосредственно с другим процессом. Не используйте его для выделения памяти. Используйте VirtualFree отменить.

HeapAlloc

выделяет любой размер памяти, который вы просите, не в больших кусках, чем VirtualAlloc. HeapAlloc знает, когда ему нужно позвонить VirtualAlloc и делает это для вас автоматически. Как malloc, но только для Windows, и предоставляет еще несколько вариантов. Подходит для выделения общих кусков памяти. Некоторые API Windows может потребоваться использовать это для выделения памяти, которую вы передаете им, или использовать его компаньон HeapFree чтобы освободить память, что они вернутся к тебе.

Танос

C способ выделения памяти. Предпочитайте это, если вы пишете на C, а не на C++, и вы хотите, чтобы ваш код работал, например, на компьютерах Unix, или кто-то специально говорит, что вам нужно его использовать. Не инициализирует память. Подходит для выделения общих кусков памяти, например HeapAlloc. Простой API. Используйте free отменить. Visual C++ ' s malloc звонки HeapAlloc.

новая

способ выделения памяти на C++. Предпочитаю это, если вы пишете на C++. Он также помещает объект или объекты в выделенную память. Используйте delete отменить (или delete[] для массивов). звонки HeapAlloc, а затем, возможно, инициализирует объекты, в зависимости от того, как вы его называете.

в последних стандартах C++ (C++11 и выше), если вам нужно вручную использовать delete, вы делаете это неправильно и нужно использовать смарт-указатель как unique_ptr вместо. Начиная с C++14, то же самое можно сказать и о new (заменяется такими функциями, как make_unique()).


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

VirtualAlloc специализированное распределение виртуальной памяти операционной системы (система виртуальных машин). Распределение в системе виртуальной машины должно выполняться с детализацией распределения, которая (детализация распределения) зависит от архитектуры. Выделение в системе виртуальной машины является одной из самых основных форм выделения памяти. Распределение виртуальных машин может принимать несколько форм, память не обязательно выделена или физически поддерживается в ОЗУ (хотя это может быть). Выделение виртуальной машины, как правило,специального назначения тип распределение, либо из-за распределения должен

  • быть очень большой,
  • должен быть общий,
  • должны быть выровнены по определенному значению (по соображениям производительности) или
  • вызывающий абонент не должен использовать всю эту память сразу...
  • etc...

HeapAlloc по сути malloc и new оба в конце концов позвонить. Он конструирован для того чтобы быть очень быстр и годен к употреблению под много разных видов сценарии распределения общего назначения. Это "куча" в классическом смысле. Кучи на самом деле настроены на VirtualAlloc, который используется для изначально зарезервировать место для размещения из ОС. После того, как пространство инициализируется VirtualAlloc, различные таблицы, списки и другие структуры данных настроены для поддержания и управления работой кучи. Некоторые из этих операций выполняются в виде динамического изменения размера (увеличения и уменьшения) кучи, адаптируя ее к конкретным условиям обычаи (частые выделения некоторого размера) и др..

new и malloc несколько то же самое,malloc по сути является точным вызовом в HeapAlloc( heap-id-default );new однако можно [дополнительно] настроить выделенную память для C++ объекты. Для данного объекта C++ будет хранить vtables в куче для каждого вызывающего объекта. Эти vtables являются перенаправлениями для выполнения и являются частью того, что дает C++ это OO-характеристики, такие как наследование, перегрузка функций, так далее...

некоторые другие распространенные методы распределения как _alloca() и _malloca() are стек based; FileMappings действительно выделяются с VirtualAlloc и установить с определенными битовыми флагами, которые обозначают эти отображения, чтобы быть типа FILE.

большую часть времени вы должны выделять память таким образом, который согласуется с использованием этой памяти ;). new В C++, malloc для C, VirtualAlloc для массивных или IPC случаев.

*** обратите внимание, что большие выделение памяти осуществляется с помощью HeapAlloc фактически отправлены в VirtualAlloc после некоторого размера (пара сотен k или 16 MB или что-то я забыл, но довольно большой :) ).

*** редактирование Я кратко заметил об IPC и VirtualAlloc, есть также что-то очень аккуратное о связанном VirtualAlloc который никто из ответчиков на этот вопрос не обсуждал.

VirtualAlloc Ex это то, что один процесс может использовать для выделения памяти в адресное пространство разные

очень важно понимать разницу между API для выделения памяти (в Windows) Если вы планируете использовать язык, который требует управления памятью (например, C или C++.) И лучший способ проиллюстрировать это ИМХО с диаграммой:

enter image description here

обратите внимание, что это очень упрощенный, специфичный для Windows вид.

способ понять эту диаграмму заключается в том, что чем выше на диаграмме выделение памяти метод есть, то более высокий уровень реализации он использует. Но давайте начнем с самого низа.

Диспетчер Памяти В Режиме Ядра

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

VirtualAlloc/VirtualFree

это низкий уровень API доступны из режим пользователя. Элемент VirtualAlloc функции, в основном вызывает ZwAllocateVirtualMemory, что в свою очередь делает быстрый syscall до ring0 чтобы перенести дальнейшую обработку в диспетчер памяти ядра. Это также самый быстрый способ зарезервировать / выделить блок нового память из всех доступных в пользовательском режиме.

но он поставляется с двумя основными условиями:

  • он выделяет только блоки памяти, выровненные по границе детализации системы.

  • он выделяет только блоки памяти размером, кратным степени детализации системы.

что это гранулярности системы? Вы можете получить его по телефону GetSystemInfo. Оно возвращается как dwAllocationGranularity

в общих чертах:

  • VirtualAlloc, HeapAlloc и др. это API-интерфейсы Windows, которые выделяют память различных типов из ОС напрямую. VirtualAlloc управляет страницами в системе виртуальной памяти Windows, в то время как HeapAlloc выделяет из определенной кучи ос. Честно говоря, вам вряд ли когда-нибудь понадобится использовать их.

  • malloc-это стандартная функция библиотеки C (и C++), которая выделяет память для вашего процесса. Реализации функций malloc будет обычно используйте один из API ОС для создания пула памяти при запуске вашего приложения, а затем выделяйте из него при выполнении запросов malloc

  • new-это стандартный оператор C++, который выделяет память, а затем вызывает конструкторы соответствующим образом в этой памяти. Он может быть реализован в терминах malloc или в терминах API ОС, и в этом случае он также обычно создает пул памяти при запуске приложения.

VirtualAlloc ===>sbrk() под UNIX

HeapAlloc ====> malloc() под UNIX

VirtualAlloc => выделяет прямо в виртуальную память, вы резервируете / фиксируете в блоках. Это отлично подходит для больших выделений, например больших массивов.

HeapAlloc/new => выделяет память в куче по умолчанию (или любой другой куче, которую вы можете создать). Это выделяет на объект и отлично подходит для небольших объектов. Куча по умолчанию является сериализуемой, поэтому она имеет гарантированное распределение потоков (это может вызвать некоторые проблемы в сценариях высокой производительности, и именно поэтому вы можете создайте свои собственные кучи).

malloc = > использует кучу времени выполнения C, похожую на HeapAlloc но это обычно для сценариев совместимости.

в двух словах, куча-это просто кусок виртуальной памяти, который управляется менеджером кучи (а не необработанной виртуальной памятью)

последняя модель в мире памяти-это файлы с отображением памяти, этот сценарий отлично подходит для большого куска данных (например, больших файлов). Это используется внутренне при открытии EXE (он не загружает EXE в памяти, просто создает файл с отображением памяти).

Comments

    Ничего не найдено.