VirtualAlloc과 HeapAlloc의 차이점은 무엇입니까?
같은 Windows 환경에서 메모리를 할당하는 방법은 많이있다 VirtualAlloc
, HeapAlloc
, malloc
, new
.
따라서 그들 사이의 차이점은 무엇입니까?
각 API는 서로 다른 용도로 사용됩니다. 또한 각각은 메모리를 다 사용할 때 올바른 할당 해제 / 해제 기능을 사용해야합니다.
VirtualAlloc
많은 옵션을 제공하지만 주로 상당히 특정한 상황에있는 사람들에게 유용한 저수준 Windows API입니다. 더 큰 청크에만 메모리를 할당 할 수 있습니다 (편집 : 4KB 아님). 필요한 상황이 있지만 이러한 상황 중 하나에 해당하는 경우 알 수 있습니다. 가장 일반적인 방법 중 하나는 다른 프로세스와 직접 메모리를 공유해야하는 경우입니다. 범용 메모리 할당에는 사용하지 마십시오. VirtualFree
할당을 해제하는 데 사용 합니다.
HeapAlloc
원하는 크기의 메모리를 할당합니다 VirtualAlloc
.. HeapAlloc
전화 VirtualAlloc
가 필요한시기를 알고 자동으로 수행합니다. 과 유사 malloc
하지만 Windows 전용이며 몇 가지 추가 옵션을 제공합니다. 일반적인 메모리 청크 할당에 적합합니다. 일부 Windows API에서는이를 사용하여 전달한 메모리를 할당하거나 해당 API를 사용하여 HeapFree
반환되는 메모리를 해제해야 할 수 있습니다.
Malloc
메모리를 할당하는 C 방식. C ++가 아닌 C로 작성하고, 예를 들어 Unix 컴퓨터에서도 코드가 작동하기를 원하거나 누군가가 그것을 사용해야한다고 특별히 말하는 경우 이것을 선호합니다. 메모리를 초기화하지 않습니다. 같은 일반적인 메모리 청크 할당에 적합합니다 HeapAlloc
. 간단한 API. free
할당을 해제하는 데 사용 합니다. Visual C ++의 malloc
호출 HeapAlloc
.
새로운
메모리를 할당하는 C ++ 방식. C ++로 작성하는 경우 선호합니다. 객체를 할당 된 메모리에도 넣습니다. 사용 delete
할당을 해제 (또는 delete[]
배열). Visual Studio에서를 new
호출 HeapAlloc
한 다음 호출 방법에 따라 개체를 초기화 할 수 있습니다.
수동으로 사용해야하는 경우 최근 C ++ 표준 (C ++ 11 이상)에서는 delete
, 당신은 잘못하고 있어요하고 사용해야하는 스마트 포인터 처럼 unique_ptr
대신. C ++ 14부터는 똑같이 말할 수 있습니다 new
(와 같은 함수로 대체 됨 make_unique()
).
SysAllocString
특정 상황에서 사용해야하는 것과 같은 몇 가지 다른 유사한 기능도 있습니다.
VirtualAlloc
OS VM (가상 메모리) 시스템의 특수 할당입니다. VM 시스템의 할당은 아키텍처에 따라 달라지는 할당 단위 (할당 단위)로 이루어져야합니다. VM 시스템에서의 할당은 메모리 할당의 가장 기본적인 형태 중 하나입니다. VM 할당은 여러 가지 형태를 취할 수 있으며 메모리가 반드시 RAM에 전용되거나 물리적으로 백업되는 것은 아닙니다 (그럴 수도 있음). VM 할당은 일반적으로 할당해야하는 특수 목적 유형의 할당입니다.
- 매우 크고
- 공유해야합니다.
- 특정 값 (성능 이유)에 따라 정렬되어야합니다.
- 발신자는이 모든 메모리를 한 번에 사용할 필요가 없습니다.
- 기타...
HeapAlloc
무엇을 본질적으로 malloc
하고 new
모두가 결국 호출합니다. 범용 할당의 다양한 유형의 시나리오에서 매우 빠르고 사용 가능하도록 설계되었습니다. 고전적인 의미의 "힙"입니다. 힙은 실제로 OS에서 할당 공간 VirtualAlloc
을 처음 예약 하는 데 사용되는에 의해 설정됩니다 . 에 의해 공간이 초기화 된 VirtualAlloc
후 다양한 테이블, 목록 및 기타 데이터 구조가 구성되어 HEAP의 작동을 유지하고 제어합니다. 이 작업 중 일부는 힙을 동적으로 크기 조정 (증가 및 축소)하는 형태로, 힙을 특정 용도 (일부 크기의 빈번한 할당) 등에 맞게 조정합니다.
new
그리고 malloc
다소 동일하며 malloc
본질적으로 정확한 호출입니다 HeapAlloc( heap-id-default )
. new
그러나 [추가적으로] C ++ 객체에 할당 된 메모리를 구성 할 수 있습니다 . 주어진 객체에 대해 C ++는 각 호출자의 힙에 vtables를 저장합니다. 이러한 vtable은 실행을위한 리디렉션이며 상속, 함수 오버로딩 등과 같은 OO 특성을 C ++에 제공하는 요소의 일부를 구성합니다.
_alloca()
및 같은 다른 일반적인 할당 방법 _malloca()
은 스택 기반입니다. FileMapping은 실제로 VirtualAlloc
해당 매핑을 유형으로 지정하는 특정 비트 플래그로 할당 되고 설정됩니다 FILE
.
대부분의 경우 해당 메모리 사용과 일치하는 방식으로 메모리를 할당해야합니다. new
C ++, malloc
C, VirtualAlloc
대규모 또는 IPC의 경우.
*** 참고로,에서 수행 한 대용량 메모리 할당 HeapAlloc
은 실제로 VirtualAlloc
일정 크기 (몇 백 k 또는 16MB 또는 내가 잊은 것이지만 상당히 큽니다 :)) 이후로 배송됩니다 .
*** 편집 나는 IPC에 대해 간략히 언급했으며이 질문에 대한 응답자 중 누구도 논의하지 않은 VirtualAlloc
관련 항목에 대해 매우 깔끔한 VirtualAlloc
것도 있습니다.
VirtualAlloc
Ex 는 한 프로세스가 다른 프로세스 의 주소 공간에 메모리를 할당하는 데 사용할 수있는 것입니다. 가장 일반적으로 이것은 CreateRemoteThread 를 통해 다른 프로세스의 컨텍스트에서 원격 실행을 얻기 위해 조합 하여 사용 됩니다 ( , 스레드는 다른 프로세스에서 실행 됨).CreateThread
메모리 관리가 필요한 언어 (예 : C 또는 C ++)를 사용하려는 경우 메모리 할당 API (Windows)의 차이점을 이해하는 것이 매우 중요합니다. IMHO를 설명하는 가장 좋은 방법은 다이어그램을 사용하는 것입니다.
이것은 매우 단순화 된 Windows 관련보기입니다.
The way to understand this diagram is that the higher on the diagram a memory allocation method is, the higher level implementation it uses. But let's start from the bottom.
Kernel-Mode Memory Manager
It provides all memory reservations & allocations for the operating system, as well as support for memory-mapped files, shared memory, copy-on-write operations, etc. It's not directly accessible from the user-mode code, so I'll skip it here.
VirtualAlloc / VirtualFree
These are the lowest level APIs available from the user mode. The VirtualAlloc
function basically invokes ZwAllocateVirtualMemory that in turn does a quick syscall to ring0
to relegate further processing to the kernel memory manager. It is also the fastest method to reserve/allocate block of new memory from all available in the user mode.
But it comes with two main conditions:
It only allocates memory blocks aligned on the system granularity boundary.
It only allocates memory blocks of the size that is the multiple of the system granularity.
So what is this system granularity? You can get it by calling GetSystemInfo. It is returned as the dwAllocationGranularity
parameter. Its value is implementation (and possibly hardware) specific, but on many 64-bit Windows systems it is set at 0x10000
bytes, or 64K
.
So what all this means, is that if you try to allocate, say just an 8 byte memory block with VirtualAlloc
:
void* pAddress = VirtualAlloc(NULL, 8, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
If successful, pAddress
will be aligned on the 0x10000
byte boundary. And even though you requested only 8 bytes, the actual memory block that you will get will be the entire page
(or, something like 4K
bytes. The exact page size is returned in the dwPageSize
parameter.) But, on top of that, the entire memory block spanning 0x10000
bytes (or 64K
in most cases) from pAddress
will not be available for any further allocations. So in a sense, by allocating 8 bytes you could as well be asking for 65536.
So the moral of the story here is not to substitute VirtualAlloc
for generic memory allocations in your application. It must be used for very specific cases, as is done with the heap below. (Usually for reserving/allocating large blocks of memory.)
Using VirtualAlloc
incorrectly can lead to severe memory fragmentation.
HeapCreate / HeapAlloc / HeapFree / HeapDestroy
In a nutshell, the heap functions are basically a wrapper for VirtualAlloc
function. Other answers here provide a pretty good concept of it. I'll add that, in a very simplistic view, the way heap works is this:
HeapCreate
reserves a large block of virtual memory by callingVirtualAlloc
internally (orZwAllocateVirtualMemory
to be specific). It also sets up an internal data structure that can track further smaller size allocations within the reserved block of virtual memory.Any calls to
HeapAlloc
andHeapFree
do not actually allocate/free any new memory (unless, of course the request exceeds what has been already reserved inHeapCreate
) but instead they meter out (orcommit
) a previously reserved large chunk, by dissecting it into smaller memory blocks that a user requests.HeapDestroy
in turn callsVirtualFree
that actually frees the virtual memory.
So all this makes heap functions perfect candidates for generic memory allocations in your application. It is great for arbitrary size memory allocations. But a small price to pay for the convenience of the heap functions is that they introduce a slight overhead over VirtualAlloc
when reserving larger blocks of memory.
Another good thing about heap is that you don't really need to create one. It is generally created for you when your process starts. So one can access it by calling GetProcessHeap function.
malloc / free
Is a language-specific wrapper for the heap functions. Unlike HeapAlloc
, HeapFree
, etc. these functions will work not only if your code is compiled for Windows, but also for other operating systems (such as Linux, etc.)
This is a recommended way to allocate/free memory if you program in C. (Unless, you're coding a specific kernel mode device driver.)
new / delete
Come as a high level (well, for C++
) memory management operators. They are specific for the C++
language, and like malloc
for C
, are also the wrappers for the heap
functions. They also have a whole bunch of their own code that deals C++
-specific initialization of constructors, deallocation in destructors, raising an exception, etc.
These functions are a recommended way to allocate/free memory and objects if you program in C++
.
Lastly, one comment I want to make about what has been said in other responses about using VirtualAlloc
to share memory between processes. VirtualAlloc
by itself does not allow sharing of its reserved/allocated memory with other processes. For that one needs to use CreateFileMapping
API that can create a named virtual memory block that can be shared with other processes. It can also map a file on disk into virtual memory for read/write access. But that is another topic.
In outline:
VirtualAlloc, HeapAlloc etc. are Windows APIs that allocate memory of various types from the OS directly. VirtualAlloc manages pages in the Windows virtual memory system, while HeapAlloc allocates from a specific OS heap. Frankly, you are unlikely to ever need to use eiither of them.
malloc is a Standard C (and C++) library function that allocates memory to your process. Implementations of malloc will typically use one of the OS APIs to create a pool of memory when your app starts and then allocate from it as you make malloc requests
new is a Standard C++ operator which allocates memory and then calls constructors appropriately on that memory. It may be implemented in terms of malloc or in terms of the OS APIs, in which case it too will typically create a memory pool on application startup.
VirtualAlloc
===> sbrk()
under UNIX
HeapAlloc
====> malloc()
under UNIX
VirtualAlloc
=> Allocates straight into virtual memory, you reserve/commit in blocks. This is great for large allocations, for example large arrays.
HeapAlloc
/ new
=> allocates the memory on the default heap (or any other heap that you may create). This allocates per object and is great for smaller objects. The default heap is serializable therefore it has guarantee thread allocation (this can cause some issues on high performance scenarios and that's why you can create your own heaps).
malloc
=> uses the C runtime heap, similar to HeapAlloc
but it is common for compatibility scenarios.
In a nutshell, the heap is just a chunk of virtual memory that is governed by a heap manager (rather than raw virtual memory)
The last model on the memory world is memory mapped files, this scenario is great for large chunk of data (like large files). This is used internally when you open an EXE (it does not load the EXE in memory, just creates a memory mapped file).
참고 URL : https://stackoverflow.com/questions/872072/whats-the-differences-between-virtualalloc-and-heapalloc
'Nice programing' 카테고리의 다른 글
ASP.NET C #에서 이메일을 보내는 방법 (0) | 2020.10.16 |
---|---|
composer create-project를 사용하여 특정 laravel 버전 설치 (0) | 2020.10.16 |
CORBA는 레거시입니까? (0) | 2020.10.16 |
Eclipse-분할보기의 동일한 .Java 파일? (0) | 2020.10.16 |
셀프 조인 설명 (0) | 2020.10.16 |