Quelle est la différences entre VirtualAlloc et HeapAlloc?
Il y a beaucoup de méthode pour allouer de la mémoire dans l'environnement Windows, tels que VirtualAlloc
, HeapAlloc
, malloc
, new
.
Ainsi, quelle est la différence entre eux?
Vous devez vous connecter pour publier un commentaire.
Chaque API est pour des utilisations différentes. Chacun exige également que vous utilisez le bon de libération/libération de la fonction lorsque vous avez terminé avec la mémoire.
VirtualAlloc
Un faible niveau, de l'API Windows qui fournit beaucoup d'options, mais il est surtout utile pour les personnes relativement à des situations spécifiques. Ne peut allouer de la mémoire dans (edit: pas moins de 4 ko) de plus gros morceaux. Il y a des situations où vous en avez besoin, mais vous savez quand vous êtes dans une de ces situations. Un des plus commune est que si vous avez à partager de la mémoire directement avec un autre processus. Ne l'utilisez pas à des fins générales de l'allocation de mémoire. Utilisation
VirtualFree
pour désallouer.HeapAlloc
Alloue quelle que soit la taille de la mémoire que vous demandez, pas de gros morceaux de
VirtualAlloc
.HeapAlloc
sait quand il a besoin de faire appelVirtualAlloc
et le fait automatiquement pour vous. Commemalloc
, mais est uniquement pour Windows, et fournit un couple de plus d'options. Adapté pour la répartition générale des morceaux de mémoire. Certaines Api Windows peut exiger que vous utiliser pour allouer de la mémoire que vous passer, ou de l'utilisation de son compagnonHeapFree
pour libérer de la mémoire qu'ils retournent à vous.malloc
Le C moyen d'allouer de la mémoire. Préférez si vous écrivez en C plutôt qu'en C++, et vous voulez que votre code de travail sur, par exemple, des ordinateurs Unix trop, ou une personne en particulier dit que vous avez besoin de l'utiliser. Ne pas procéder à l'initialisation de la mémoire. Adapté pour la répartition générale des morceaux de mémoire, comme
HeapAlloc
. Une API simple. Utilisationfree
pour désallouer. Visual C++malloc
appelsHeapAlloc
.nouveau
Le C++ moyen d'allouer de la mémoire. Préférez si vous écrivez en C++. Il met un objet ou des objets dans la mémoire allouée, trop. Utilisation
delete
pour désallouer (oudelete[]
pour les tableaux). Visual studionew
appelsHeapAlloc
, et puis peut-être initialise les objets, selon comment vous l'appelez.Au cours des dernières normes C++ (C++11 et ci-dessus), si vous avez manuellement utilisation
delete
, vous le faites mal et doit utiliser un pointeur intelligent commeunique_ptr
à la place. À partir de C++14,, la même chose peut être dit denew
(remplacé avec des fonctions telles quemake_unique()
).Il ya aussi un couple de d'autres fonctions similaires comme
SysAllocString
que vous avez peut-être dit que vous avez à utiliser dans des circonstances particulières.HeapAlloc
] pour allouer de la mémoire que vous passer, ou de l'utilisation de son compagnonHeapFree
pour libérer de la mémoire qu'ils retournent à vous." <<< des exemples de cela?VirtualAlloc
est une institution spécialisée dans l'allocation de l'OS de la mémoire virtuelle (VM) du système. Attributions dans le système VM doit être faite à une granularité d'allocation (la granularité d'allocation) est dépendants de l'architecture. Répartition dans le système VM est l'un des la plupart des formes de base de l'allocation de mémoire. VM allocations peuvent prendre plusieurs formes, la mémoire n'est pas forcément dédié ou physiquement sauvegardés dans la mémoire RAM (mais il peut l'être). VM allocation est généralement un à des fins spéciales type d'allocation, soit en raison de la répartition deHeapAlloc
est essentiellement ce quemalloc
etnew
tous deux fini par appeler. Il est conçu pour être très rapide et utilisable sous beaucoup de différents types de scénarios d'usage général de répartition. C'est le "Tas", dans un sens classique du terme. Des tas sont en fait de l'installation par unVirtualAlloc
, qui est ce qui est utilisé pour initialement réserve de l'allocation de l'espace de l'OS. Après l'espace est initialisé parVirtualAlloc
, les différents tableaux, listes et autres structures de données sont configurés pour maintenir et contrôler le fonctionnement de la pile. Une partie de cette opération est dans la forme de dimensionnement dynamique (croissance et de la réduction) le tas, en adaptant le tas à certains usages (allocations de fréquentes d'une certaine taille), etc..new
etmalloc
sont un peu les mêmes,malloc
est essentiellement exacte de l'appel enHeapAlloc( heap-id-default )
;new
cependant, peut [en outre] configurer la mémoire allouée pour le C++ objets. Pour un objet donné, C++ va stocker les vtables sur le tas pour chaque appelant. Ces vtables sont des redirections pour l'exécution et font partie de ce qui donne du C++ c'est OO caractéristiques comme l'héritage, surcharge de fonctions, etc...D'autres méthodes de répartition comme
_alloca()
et_malloca()
sont pile base; FileMappings sont vraiment alloué avecVirtualAlloc
et de définir, avec en particulier les indicateurs de bits qui désignent ces correspondances pour être de typeFILE
.La plupart du temps, vous devez allouer de la mémoire dans une manière qui est compatible avec l'utilisation de la mémoire ;).
new
en C++,malloc
pour C,VirtualAlloc
pour massif ou de l'IPC cas.*** Notez que les grandes allocations de mémoire fait par
HeapAlloc
sont effectivement expédiées àVirtualAlloc
après une certaine taille (quelques centaines de k ou 16 MO ou quelque chose que j'oublie, mais assez gros 🙂 ).*** EDIT
J'ai brièvement fait remarquer à propos de la CIB et
VirtualAlloc
, il y a aussi quelque chose de très agréable sur un liésVirtualAlloc
qui aucun des répondants à cette question ont discuté.VirtualAlloc
Ex est ce qu'un processus peut utiliser pour allouer de la mémoire dans un espace d'adressage d'un différents processus. Plus généralement, il est utiliséen combinaisonpour obtenir de l'exécution à distance dans le cadre d'un autre processus via CreateRemoteThread (similaire àCreateThread
, le fil est tout simplement courir dans l'autre processus).Il est très important de comprendre la distinction entre l'allocation de mémoire Api (dans Windows) si vous prévoyez sur l'utilisation d'un langage qui nécessite la gestion de la mémoire (comme le C ou le C++.) Et la meilleure façon d'illustrer mon humble avis est un diagramme:
Remarque que c'est une très simplifié, spécifique à Windows de vue.
Le moyen de comprendre ce schéma est le plus élevé sur le diagramme de la méthode d'allocation de mémoire est, le niveau supérieur mise en œuvre qu'il utilise. Mais commençons par le bas.
En Mode Noyau Gestionnaire De Mémoire
Elle offre à tous la mémoire réservations & les allocations pour le système d'exploitation, ainsi que le soutien pour fichiers mappés en mémoire, mémoire partagée, de copie sur écriture opérations, etc. Ce n'est pas directement accessible à partir de l'utilisateur en mode code, donc je vais passer ici.
VirtualAlloc /VirtualFree
Ce sont les niveau le plus bas Api disponibles à partir de la en mode utilisateur. Le
VirtualAlloc
fonction essentiellement appelle ZwAllocateVirtualMemory qui à son tour a fait un rapide syscall àring0
de réserver un traitement supplémentaire pour le gestionnaire de mémoire du noyau. C'est aussi la méthode la plus rapide pour réserver/allouer un bloc de mémoire disponibles dans le mode utilisateur.Mais il est livré avec deux conditions principales:
Il n'alloue de la mémoire des blocs alignés sur le système de granularité de la frontière.
Il n'alloue des blocs de mémoire de la taille qui est le multiple du système de granularité.
Quel est donc ce système de granularité? Vous pouvez l'obtenir en appelant GetSystemInfo. Il est retourné en tant que
dwAllocationGranularity
paramètre. Sa valeur est mise en œuvre (et éventuellement du matériel spécifique, mais sur de nombreux systèmes Windows 64 bits, il est fixé à0x10000
octets, ou64K
.Donc, ce que tout cela signifie, c'est que si vous essayez d'affecter, disons seulement 8 octets du bloc de mémoire avec
VirtualAlloc
:En cas de succès,
pAddress
sera aligné sur le0x10000
frontière d'octet. Et même si vous avez demandé à seulement 8 octets, le bloc de mémoire que vous obtiendrez sera la totalité de lapage
(ou quelque chose comme4K
octets. Le exacte de la taille de la page est retourné dans ledwPageSize
paramètre.) Mais, en plus de cela, l'ensemble du bloc de mémoire couvrant0x10000
octets (ou64K
dans la plupart des cas) à partir depAddress
ne être disponible pour tout complément d'allocations. Donc dans un sens, par l'affectation de 8 octets, vous pourriez aussi bien demander 65536.Donc la morale de l'histoire ici n'est pas de substituer
VirtualAlloc
génériques des allocations de mémoire dans votre application. Il doit être utilisé pour des cas très spécifiques, comme c'est le cas tas ci-dessous. (Généralement pour la réservation/l'allocation de grands blocs de mémoire.)À l'aide de
VirtualAlloc
de manière incorrecte peut entraîner une fragmentation de la mémoire.HeapCreate /HeapAlloc /HeapFree /HeapDestroy
En un mot, la tas fonctions sont essentiellement un wrapper pour
VirtualAlloc
fonction. D'autres réponses ici de fournir un très bon concept. Je vais ajouter que, dans un très simpliste, la façon tas fonctionne, c'est ce:HeapCreate
se réserve un grand bloc de mémoire virtuelle en appelantVirtualAlloc
en interne (ouZwAllocateVirtualMemory
pour être précis). Il instaure également une structure de données interne qui permet de suivre plus petite taille attributions au sein de la réserve de bloc de mémoire virtuelle.Tous les appels à
HeapAlloc
etHeapFree
ne sont pas réellement allouer/libre toutes les nouvelles de la mémoire (à moins, bien sûr, la demande dépasse ce qui a déjà été réservés dansHeapCreate
), mais plutôt qu'ils appareil (oucommit
) précédemment réservé grande partie, par la dissection en plus petits blocs de mémoire que l'une des demandes de l'utilisateur.HeapDestroy
appelle à son tourVirtualFree
qui fait libère la mémoire virtuelle.Donc tout cela fait tas fonctions des candidats parfaits pour les allocations de mémoire dans votre application. Il est grand de taille arbitraire de l'allocation mémoire. Mais un petit prix à payer pour la commodité de la tas fonctions est qu'elles introduisent une légère surcharge sur
VirtualAlloc
lors de la réservation de plus grands blocs de mémoire.Une autre bonne chose à propos de tas est que vous n'avez pas vraiment besoin d'en créer un. Il est généralement créé pour vous lors de votre démarrage du processus. On peut donc y accéder en appelant GetProcessHeap fonction.
malloc /gratuit
Est spécifique à la langue de l'enveloppe pour la tas fonctions. Contrairement à
HeapAlloc
,HeapFree
, etc. ces fonctions de travail, non seulement si votre code est compilé pour Windows, mais aussi pour d'autres systèmes d'exploitation tels que Linux, etc.)C'est un moyen recommandé d'allouer/libérer de la mémoire si vous programmez en C (Sauf si vous êtes un codage spécifique du noyau pilote de périphérique en mode.)
nouveau /supprimer
Venir comme un de haut niveau (bien, pour
C++
) gestion de la mémoire les opérateurs. Ils sont spécifiques à laC++
de la langue, et commemalloc
pourC
, sont aussi les wrappers pour lesheap
fonctions. Ils ont aussi tout un tas de leur propre code qui traiteC++
-initialisation spécifique de constructeurs, de libération de la mémoire dans les destructeurs, le déclenchement d'une exception, etc.Ces fonctions sont un moyen recommandé d'allouer/libérer de la mémoire et des objets si vous programmez en
C++
.Enfin, un commentaire à faire à propos de ce qui a été dit dans d'autres réponses sur l'utilisation de
VirtualAlloc
pour partager la mémoire entre les processus.VirtualAlloc
par lui-même ne permet pas le partage de ses réservés/mémoire allouée avec d'autres processus. Pour cela on a besoin d'utiliserCreateFileMapping
API qui peut créer un nom de bloc de mémoire virtuelle qui peut être partagé avec d'autres processus. Il peut également mapper un fichier sur le disque dans la mémoire virtuelle pour les accès en lecture/écriture. Mais c'est un autre sujet.Dans les grandes lignes:
VirtualAlloc, HeapAlloc etc. sont les Api Windows qui alloue de la mémoire de différents types de l'OS directement. VirtualAlloc gère des pages dans la mémoire virtuelle de Windows système, tandis que HeapAlloc alloue à partir d'un système d'exploitation spécifique tas. Franchement, vous êtes peu probable qu'on ait besoin d'utiliser eiither d'entre eux.
malloc est un Standard de C (et C++) de la bibliothèque de fonction qui alloue de la mémoire pour votre processus. Les implémentations de la fonction malloc généralement utiliser l'un de l'Api du système d'exploitation pour créer un pool de mémoire lorsque votre application démarre, puis d'attribuer à partir de ce que vous faites malloc demandes
nouveau Standard C++ opérateur qui alloue de la mémoire et appelle ensuite les constructeurs de manière appropriée que la mémoire. Il peut être mis en œuvre en termes de malloc ou dans les termes de l'Api du système d'exploitation, auquel cas, il sera lui aussi en général créer un pool de mémoire de démarrage de l'application.
VirtualAlloc
===>sbrk()
sous UNIXHeapAlloc
====>malloc()
sous UNIXVirtualAlloc
=> Alloue directement dans la mémoire virtuelle, vous réserve de s'engager dans des blocs. C'est idéal pour les grandes affectations, par exemple, de grands tableaux.HeapAlloc
/new
=> alloue de la mémoire sur le tas par défaut (ou de tout autre segment de mémoire que vous pouvez créer). Il alloue par objet et est idéal pour les petits objets. Le segment par défaut est sérialisable, il a donc la garantie du fil de répartition (ce qui peut causer quelques problèmes sur la haute performance des scénarios et c'est pourquoi vous pouvez créer votre propre tas).malloc
=> utilise le runtime C tas, semblable àHeapAlloc
mais il est commun pour la compatibilité des scénarios.En un mot, le tas est juste un morceau de la mémoire virtuelle qui est régi par un gestionnaire de tas (plutôt que brut de la mémoire virtuelle)
Le dernier modèle sur le monde de la mémoire est fichiers mappés en mémoire, ce scénario est idéal pour grande partie de données (comme les gros fichiers). Ce est utilisé en interne lorsque vous ouvrez un fichier EXE (il ne charge pas le fichier EXE dans le mémoire, crée un fichier mappé en mémoire).