By Leezy_2000
2003-10-8 17:01
Third, talk about HEAP
(Given that Matt Pietrek has made a very detailed explanation of the HEAP of the 9x system in its "Windows 95 System Program Design,", the content involved here will be limited to Win2000)
HEAP is in contrast to Stack, you need to manually manage the application and release of each memory (without garbage collection mechanism), and for C / C programmers, how much the way to operate HEAP is too much. Below is a list of almost all methods that can operate the memory:
Malloc / free
NEW / Delete
Globalalloc / GlobalFree
Localalloc / LocalFree
Heapalloc / HeapFree
Where Malloc / Free is provided by the runtime library, New / Delete is a built-in operator. They all use their own stacks of running time libraries. The runtime library has its own independent heap under 2000 and Win9x. This means that as long as you start the process, you will have at least two piles, one as the process default, one to the C / C runtime library.
GlobalAlloc / GlobalFree and Localalloc / LocalFree have now lost their original meaning, and allocate memory from the process default heap.
HeapAlloc / HeapFree allocates memory from the specified stack.
Single to allocate memory (New / Delete also works and sectors), all these ways ultimately attribute to a point 2000 and 98 are Heapallocc. So Microsoft will temporarily emphasize that GlobalLoc / GlobalFree and Localalloc / LocalFree will be slower. It is recommended to use HeapAlloc, but because global ** and local ** have a simplex use interface, even in the source code provided in Microsoft, they are still large use. It must be pointed out that Heapalloc does not have its own implementation in kernel32.dll, but forward all calls to NTDLL.rtLallocateHeap. The following is taken from the MSDN (Figure 2), which should help us understand the same heap-related API.
The operation of the inside of the heap is a bit similar to the SGI STL, which is generally, and the OS maintains several linked lists for each heap, and stores blocks that specify the size range on each linked list. When you assign memory, the operating system determines the assignment from the size you provide, then find the appropriate block from that list and return its linear address to you. If you ask the size, you can't find it in the existing block, then you have allocated a large amount of memory (using Virtualalloc), then cut him, and then return the linear address of a block. This is just a general situation that the operating system always updates its own stack algorithm to increase the speed of the heap operation.
The pile itself (including the flag and linked watch, etc.) is stored in the Heap Header, and the stacking handle is pointing to the Heap Header pointer, and the structure of the Heap header is not open. We will try to do some analysis later. Very interesting is Microsoft repeatedly emphasized that the Heapid that is only valid for the Toolhelp API is actually a heap handle.
It turned out to prepare for some structures in the inside, but later I think so practical value is not very big, and the strength is not small. Therefore, there is no specific operation. But here is open to the implementation of the implementation of various changes in various changes in monitoring stacks, I hope to help everyone. This small program is very simple, the main task is the change of all the heaps in the process. Since comparing two linked lists, the STL VECTOR container and some algorithms are used to reduce encoding. At the same time, in order to make STL's memory use to interfere with the objects we want to monitor, we need to build your own distributor to use the heap you created separately. In addition, special attention is required because the TOOLHELP API Heap32Next does not allow disturbances to any pile during operation (otherwise he always returns true), causing us to use the vector and keep sufficient space in advance. (Another way to access some of the information inside the pile is to use the Heapwalk API to see personal preferences). The running process of the program is such, first enumerate the heap existing in the current process, and store the result into a set type of variable heapid1, then create your own stack to the dispenser and use the stack in the process. Make an enumeration again and store the results in another set type of variable HeapID2, which can call set_difference to find the ID of our new heap, and then listed in the inside of the queue will exclude the heap represented by this ID. Next, you can store the information of the inside of the stack in the two points to the corresponding vector, compare the two vectors, and the change in the allocation of the memory operation can be obtained.
(Figure 2 from msdn by Murali R. Krishnan)
Here are some unresolved issues, which is interested in exploring themselves.
What is the HEAP HEADER structure?
Organize how to organize memory blocks? (Is it a list?
The description of each small piece is there? (If it is a list, you should have a pointer to connect these small pieces to each other.)