1. WindowsMain Memory Management channels under the platform
Application |
Release |
New |
Delete |
Malloc |
Free |
Cotaskmemalloc |
Cotaskmemfree |
Imalloc: alloc |
Imalloc/free |
Globalalloc |
Globalfree |
Localalloc |
Localfree |
Heapalloc |
Heapfree |
Virtualalloc |
Virtualfree |
2. Call Link
Level 1: Win32 API, as a system interface, provides a set of interfaces for operating virtual memory;
Layer 2: heap is a part of the virtual memory. Win32 API provides a set of interfaces for operating the heap memory. However, these interfaces are based on the interfaces for operating the virtual memory.
Layer 3: The C run-time library on Windows uses heap APIs to implement malloc and free.
We can see that there is a single hierarchical relationship between these dynamic memory operations. The lowest layer of this layer is the virtual memory API, it can be said that these methods are built on the virtual memory API.
The call relationship is shown in the following table: New-> malloc-> heapalloc-> virtualalloc-> driver's _ pagealloc
Caller |
Called |
Msvcrt. malloc |
Kernel32.heapalloc (NTDLL. rtlallocateheap) |
Kernel32.localalloc |
Ntdll. rtlallocateheap |
Kernel32.globlealloc |
Ntdll. rtlallocateheap |
Kernel32.heapalloc |
Ntdll. rtlallocateheap (ing) |
Kernel32.virtualalloc |
Kernel32.virtualallocex |
Kernel32.virtualallocex |
Ntdll. ntallocatevirtualmemory |
Ntdll. rtlallocateheap |
Ntdll. ntallocatevirtualmemory |
Ntdll. ntallocatevirtualmemory |
Ntdll. kifastsystemcall |
Ntdll. kifastsystemcall |
Sysenter command (0f34) |
3. Method Parsing
3.1Virtual Memory API
As the "core" interface for Virtual Memory operations provided by windows, virtual memory APIs should be the most common among several methods, it is also the most powerful method. In Windows, memory management is divided into two parts. The global memory is the memory managed by the system, so all processes can access the memory, and each process has its own memory space, this is the virtual memory space, and the virtual memory space is relatively large. When the physical memory is insufficient, the system will save the virtual memory data to the hard disk, in this way, as long as the disk space is large enough, each process can use 3G memory. Virtual Memory allocation can be used as the main way to allocate memory in the program, such as a large amount of data buffer, Dynamic Allocation of memory space. Using the virtualalloc function to allocate memory is faster than the global memory.
1: LPVOID WINAPI VirtualAlloc( __in_opt LPVOID lpAddress, __in SIZE_T dwSize, __in DWORD flAllocationType, __in DWORD flProtect );
Lpaddress is the address starting with the specified memory.
Dwsize indicates the size of the allocated memory.
Flallocationtype is the type of memory allocated.
Flprotect is the permission to access the allocated memory.
1: void MemVirtual(void) {
2: // allocate the new memory size.
3: UINT nNewSize = (UINT) ceil(1500 / 1024.0) * 1024;
4: PBYTE pNewBuffer = (PBYTE) VirtualAlloc(NULL,nNewSize,MEM_COMMIT,PAGE_READWRITE);
5: if (pNewBuffer){
6: // test the virtual memory.
7: ZeroMemory(pNewBuffer,1500);
8: memcpy (pnewbuffer, _ T ("virtual memory allocated successfully \ r \ n"), sizeof (_ T ("virtual memory allocated successfully \ r \ n ")));
9: OutputDebugString((LPWSTR)pNewBuffer);
10: // release the allocated memory. The third parameter must be mem_release.
11: VirtualFree(pNewBuffer,0,MEM_RELEASE);
12: }
13: }
3.2Heap memory API
There are two kinds of allocation situations in the process's private memory space allocation: stack-based memory allocation and heap-based memory allocation. Heapalloc is used to allocate heap memory, which is called when the new operator allocates memory. Here, "Heap" refers to an object owned by a process (there are many objects in windows, such as window, icon, and brush). When we create a heap object, we can get the handle of this object, then we can use this handle to use dynamic memory, and finally destroy this object.
1: LPVOID WINAPI HeapAlloc(__in HANDLE hHeap,__in DWORD dwFlags,__in SIZE_T dwBytes);
Hheap is the starting position of the Process heap memory.
Dwflags indicates heap memory allocation.
Dwbytes is the size of heap memory allocated.
1: void MemHeap(void){
2: const int nHeapSize = 1024;
3: PBYTE pNewHeap = (PBYTE) ::HeapAlloc(GetProcessHeap(), 0, nHeapSize);
4: if (pNewHeap){
5: // test heap memory allocation.
6: ZeroMemory(pNewHeap,nHeapSize);
7: memcpy (pnewheap, _ T ("heap memory allocated successfully \ r \ n"), sizeof (_ T ("heap memory allocated successfully \ r \ n ")));
8: OutputDebugString((LPWSTR)pNewHeap);
9: // release the memory
10: BOOL bRes = ::HeapFree(GetProcessHeap(), 0, pNewHeap);
11: if (bRes != TRUE){
12: outputdebugstring (_ T ("memory release error \ r \ n "));
13: }
14: }
15: }
3.3Localalloc/globalalloc
These two functions are two legacy functions in Win16 API. Win32 API only contains these two functions to maintain compatibility. These two functions use the heap memory API to operate a "special" heap object: The default heap object of the process. Each process creates a default heap object during initialization and destroys the default heap object at the end of the process. The difference between localalloc and globalalloc is only manifested in the Win16 environment. In the Win16 environment, the memory address is obtained through the offset within the segment, localalloc () memory can only be allocated within the same segment, while globalalloc can access the memory Across the segment boundary. In the Win32 environment, there is no such restriction on memory access, so they show the same function. Since the heap memory API can fully implement both of them, we do not recommend using these two functions in Win32.
In Windows, a function is very useful, that is, the clipboard function, which can exchange data with another program from one program, that is, the two processes can share data. To implement this function, the Windows system has corresponding support at the underlying layer, that is, the memory of the high-end address is the system memory, so that different processes can share data. Therefore, the globalalloc function is called to allocate system memory so that different processes can share data, that is, the clipboard function, and the memory can be allocated within a process, access Data in another process and delete the memory.
1: HLOCAL WINAPI LocalAlloc(__in UINT uFlags,__in SIZE_T uBytes);
2: HGLOBAL WINAPI GlobalAlloc (__in UINT uFlags, __in SIZE_T dwBytes);
Sample Code:
1: void MemGlobal(void) {
2: // allocate global memory.
3: BYTE* pGlobal = (BYTE*)::GlobalAlloc(GMEM_FIXED,1024);
4: if (!pGlobal) {
5: return;
6: } else {
7: // test the global memory
8: ZeroMemory(pGlobal,1024);
9: memcpy (pglobal, _ T ("memory allocated successfully \ r \ n"), sizeof (_ T ("memory allocated successfully \ r \ n ")));
10: OutputDebugString((LPWSTR)pGlobal);
11: }
12: // release the global memory.
13: ::GlobalFree((HGLOBAL)pGlobal);
14: }
3.4Malloc/free
These two functions are the two most frequently used functions, which are highly portable because they are part of the standard C library. Here, "portability" means that their code can be compiled and translated on different platforms, while the specific implementation of the C run-time library on different platforms is platform-related, the malloc () and free () in the C run-time library on windows are implemented by calling the heap memory API. It is worth noting that the C run-time Library has an independent heap object. We know that when an application is initialized, the C run-time library is initialized first, then there is the entry function of the application, and the heap object is created when the C run-time library is initialized.
For dynamic-linked C run-time libraries, the Runtime Library is initialized only once, and for static-connected runtime libraries, each link is initialized once, therefore, the runtime libraries of each static link have different heap objects. In this way, problems may occur in some situations, causing program crash. For example, an application calls multiple DLL, except one DLL, other DLL, the application itself dynamically connects to the runtime so that they use the same heap object. A dll uses a static connection Runtime Library, which has a heap object different from other DLL. When the dll exists and is released in another DLL, the problem arises.
3.5KeywordsNew/keyword Delete
These two words are the built-in keywords (keyword) of C ++ ). When the C ++ compiler sees the keyword new, for example:
Cmyobject * pobj = new cmyobject;
The compiler executes the following two tasks:
A) dynamically allocate necessary memory on the stack. This task is completed by a global function void *: Operator new (size_t) provided by the compiler. It is worth noting that any class can reload this global function. If the class reloads this function, the one that is reloaded by the class will be called.
B) Call the cmyobject constructor to initialize the newly generated object. Of course, if the assigned object is the basic data type in C ++, no constructor call will be performed.
If you want to go deep into the global function void *: Operator new (size_t), we will find that the specific implementation of this function is to allocate memory by calling malloc, and on the win platform, malloc finally calls the heapalloc method.
3.6Cotaskmemalloc/imalloc
Cotaskmemalloc is used for COM objects. It allocates memory in the default heap of the process.
The imalloc interface is a re-encapsulation of cotaskmemalloc/cotaskmemfree.