Windows Memory Management (2)

Source: Internet
Author: User

Because the pages of the working set reside in the physical memory, access to these pages does not involve disk I/O, which is relatively fast; otherwise, if the code executed or accessed data is not in the work set, additional disk I/O will be triggered, thus reducing the program running efficiency. In an extreme situation, thrashing is called as a process, that is, most of the execution time of a program is spent on page adjustment operations, rather than code execution.

As mentioned above, when you call a page, the virtual memory manager not only calls the required page, but also transfers the pages nearby to the memory. Based on these knowledge, developers should consider the following two factors if they want to improve program running efficiency.

(1) For the code, write compact code as much as possible. The ideal situation is that the working set never reaches the maximum threshold. When you call a new page, you do not need to replace the pages that have been loaded into the memory. According to the locality feature, previously executed code and accessed data may be re-executed or accessed later. In this way, when the program is executed, the number of page missing errors will be greatly reduced, that is, the disk I/O is reduced, in Figure 4-6, you can also see the number of page missing errors that occurred during program execution. Even if this is not possible, compact code often means that the code to be executed next is more likely to be on the same page or adjacent pages. Based on the time locality feature, 80% of the program's time is spent on 20% of the Code. If you can compact and merge the 20% code as much as possible, it will undoubtedly greatly improve the overall running performance of the program.

(2) for data, try to put together the data that will be accessed together (such as the linked list. In this way, when accessing the data, because they are on the same page or adjacent pages, only one page adjustment operation is required. Otherwise, if the data is scattered across multiple pages (or even worse, these pages are not adjacent), each access to the data will lead to a large number of page missing errors, reducing performance. Using the reserved and submitted two-step mechanism provided by Win32, You can reserve a large block of space for the data that will be accessed together. At this time, no actual storage space is allocated, and the memory is submitted as needed when the data is generated during subsequent execution. In this way, you do not waste real physical storage (including the disk space and physical memory space of paging files), but can also use the locality feature. In addition, the memory pool mechanism is also based on similar considerations.

4.1.6 Win32 memory APIs

On the Win32 platform, developers can use the following five groups of functions to use the memory (to complete the application and release operations ).

(1) traditional CRT functions (malloc/free series): Because of the platform independence of this group of functions, this group of functions is preferred if the program will be transplanted to other non-Windows platforms. It is also because this group of functions is not proprietary to Win32 and the information about this group of functions is not described in detail here.

(2) global heap/local heap functions (GlobalAlloc/LocalAlloc series): these functions are reserved for backward compatibility. On the Windows 3.1 platform, global heap is the heap of all processes in the system, including system processes and user processes. Their applications for the global heap memory will be staggered, so that an accidental memory usage error of a user process will cause the entire operating system to crash. The local heap is also called the *** heap ***. It corresponds to the global heap and the local heap is private to each process. The process uses LocalAlloc to apply for memory from its local heap without interfering with each other. In addition, the process cannot dynamically apply for memory through another user-defined heap or other methods. On the Win32 platform, due to security considerations, the global heap has been deprecated, and the local heap has also been renamed "process heap ". To enable applications previously written for Windows 3.1 to run on the new Win32 platform, the GlobalAlloc/LocalAlloc series functions are still in use, however, all these functions allocate memory from the process heap. Moreover, the Win32 platform also allows the process to generate and use new user-defined heap in addition to the process heap. Therefore, we recommend that you do not use GlobalAlloc/LocalAlloc functions for memory operations on the Win32 platform, therefore, this group of functions is not detailed here.

(3) virtual memory functions (VirtualAlloc/VirtualFree series): These functions operate on the memory directly by reserving and committing the virtual memory address space, therefore, they provide developers with the maximum degree of freedom, but correspondingly add more burden to their memory management work. This set of functions is suitable for opening up space for large continuous data structure arrays.

(4) memory ing file function (CreateFileMapping/MapViewOfFile series): The system uses the memory ing file series to upload the. exe or. dll files. For developers, on the one hand, this set of functions can be used to conveniently operate hard disk files, without the need to consider tedious file I/O operations. On the other hand, multiple processes running on the same machine can share data through memory ing file functions (this is also the most efficient and convenient way to share and communicate data between processes on the same machine) method ).

(5) HeapCreate/HeapAlloc: Each heap on the Win32 platform is private to each process. Each process, except for the default process heap, you can also create a custom heap. When the program needs to dynamically create multiple small data structures, the heap function series is the most suitable. In general, the CRT function (malloc/free) is implemented based on the heap memory function.

1. Virtual Memory

There are four pairs of VM-related functions, namely VirtualAlloc/VirtualFree, VirtualLock/VirtualUnlock, VirtualQuery/VirtualQueryEx, and VirtualProtect/VirtualProtectEx. The most important one is the first pair, which is described in this section.

LPVOID VirtualAlloc (

LPVOID lpAddress,

DWORD dwSize,

DWORD flAllocationType,

DWORD flProtect

);

Based on different flallocationtypes, virtualalloc can retain a virtual memory area (MEM _ Reserve) or submit a virtual memory area (mem_commit ). When retained, there are no other resources, such as paging file space or actual physical memory, in addition to modifying the VAD of the process (specifically adding one), and no page table items are even created. Therefore, it is very fast, and the execution speed has nothing to do with the size of the reserved space. Because the reserved address only allows the Memory Manager to reserve a virtual address space, and there is no real storage (paging file space on the hard disk or physical memory), access to the reserved address will cause access violations, this is a serious error that causes the process to exit. On the contrary, when submitting virtual memory, the memory manager must open up the actual storage space from the system paging file, therefore, the speed is slower than the retention operation. However, it should be noted that at this time, the physical memory does not immediately allocate space to correspond to the virtual memory space, and even no corresponding page table items are created, however, the submitted operation modifies the VAD entry accordingly. Only when an address in this virtual address space is accessed for the first time, the Virtual Memory Manager searches for the VAD due to a page disconnection, dynamically creates the PTE Based on the VAD content, and then based on the PTE information, allocate the physical memory page and actually access the memory. As you can see,The actual time-consuming operation is not the commit memory, but the first access to the commit memory! ThisLazy-evaluationThe mechanism is very beneficial to the program running performance, because if a program commits a large segment of memory, but only occasionally accesses some pages, if this lazy-evaluation mechanism is not available, submitting large segments of memory greatly reduces the system performance.

In contrast, virtualfree releases the memory. It provides two options: You can release the submitted memory to the system, but do not release the reserved virtual memory address space; you can also release the virtual memory address space while releasing the memory, so that the status of this virtual memory address space changes back to the initial free state. If the memory is submitted, virtualfree is slow because it releases the real storage space. If you only release the reserved virtual memory address space, this operation will be fast because you only need to modify VAD.

In addition,VirtualLockEnsure that a block remains in the physical memory during the lock period. Therefore, access to this memory will not cause page missing interruption. The memory of the lock is unlocked using VirtualUnlock. Because VirtualLock locks the memory in the physical memory. If these memories are not accessed frequently, other frequently used memory increases the probability of being paged out, this reduces the overall performance of the system. Therefore, the VirtualLock/VirtualUnlock function is not recommended in actual use. VirtualQuery can obtain the status of the virtual memory block where the pointer is located, such as the base address of the virtual memory area on the page where the pointer is located, and the status of the region. VirtualProtect can be used to modify the access protection flag of the submitted memory page in a region.

2. Memory ing File

The memory ing file is mainly used for three purposes. Windows uses it to effectively use exe and dll files, and developers use it to convenientlyAccess Hard Disk Files, Or implementMemory sharing between different processes. The first one is not described in detail here. It only describes the last two uses. First, we will discuss the mechanism it provides to facilitate access to hard disk files. Once this mechanism is used to map a hard disk file (in part or all) to a virtual address space of a process, read and Write the content of this file just like accessing a variable through a pointer. If pViewMem is the first address mapped to the memory, then:

* PViewMem = 100; // write the 1st bytes of the file.

Char ch = * (pViewMem + 50); // read the 50th bytes of the file

The following describes how to use this mechanism.

(1) Create or open a hard disk file.

This step is used to obtain the handle of a file object. You can use the CreateFile function to create or open a file:

HANDLE CreateFile (

PCSTR pszFileName,

DWORD dwDesiredAccess,

DWORD dw1_mode,

PSECURITY_ATTRIBUTES psa,

DWORD dwCreationDisposition,

DWORD dwFlagsAndAttributes,

HANDLE hTemplateFile );

The pszFileName parameter indicates the path name of the file. The dwDesiredAccess parameter indicates how the file content will be accessed. This parameter includes 0, GENERIC_READ, GENERIC_WRITE, and GENERIC _ READ | GENERIC_WRITE, which indicate "neither READ nor write" (used only to READ the file attribute), "read-only", "Write-only", and "Both readable and writable". The dw1_mode parameter is used to limit any other access permissions to the file, including the preceding four types. The remaining parameters are not described in detail because they have little to do with the issues to be discussed.

If this function succeeds, a file object handle is returned; otherwise, INVALID_HANDLE _ VALUE is returned.

(2) create or open a file ing kernel object.

You also need to have a file ing kernel object that maps the file content to the memory. If this kernel object already exists, you only need to open it through the OpenFileMapping function. This function returns the handle of the named object. In most cases, you need to create a new file ing Kernel Object and call the CreateFileMapping function:

HANDLE CreateFileMapping (

HANDLE hFile,

PSECURITY_ATTRIBUTES psa,

DWORD fdwProtect,

DWORD dwMaximumSizeHigh,

DWORD dwMaximumSizeLow,

PCTSTR pszName );

The hFile parameter is the file kernel object handle returned in the first step. The psa parameter specifies the security characteristics of the kernel object and is not described in detail; the fdwProtect parameter specifies the access permission for the file content mapped to the Memory Page. This permission must correspond to the file access permission in step 1; the dwMaximumSizeHigh and dwMaximumSizeLow parameters indicate the maximum space size of the ing. Because Windows supports 64-bit files, two 32-bit parameters are required. pszName is the kernel object name.

In this step, only a file ing kernel object is created, and no virtual address space is reserved or submitted, and no physical memory page is allocated to store the file content.

(3) map the content of the file to the virtual address space of the process.

Before accessing the file content, you must map the content of the file to be accessed to the memory and use the MapViewOfFile function:

PVOID MapViewOfFile (

HANDLE hFileMappingObject,

DWORD dwDesiredAccess,

DWORD dwFileOffsetHigh,

DWORD dwFileOffsetLow,

SIZE_T dwNumberOfBytesToMap );

The parameters are respectively used to map the handle of the memory ing kernel object, and the mapped file content is used to access the memory page, the offset and size of the starting part of the file content to be mapped in the file. During the ing, you do not need to map all the content of the entire file to the memory at one time.

The operation of this function includes pre-setting a region of the required ing size from the virtual address space of the process, and then submitting. When submitting a file, it does not open up space from the system's page file to serve as the backup storage for this region, but is the specified area of the file mapped to the kernel object in the memory.The only difference from the use of virtual memory is that the backup storage in the virtual address space area is different, and the others are the same.Similarly, the physical memory is not actually opened up until the returned pointer is used to access the file content mapped to the memory. The system allocates a physical memory page because of a page missing error, and page the corresponding content in the file storage to the physical memory page.

4) access the file content.

Now, you can access the file content mapped to the memory by using the pointer returned by the MapViewOfFile function, as shown in this section.

Here, we need to remind you of the modification results when you modify the file content through this pointer.Usually not immediatelyIt is reflected in the file, because it is actually modifying the data on the page transferred to the physical memory. Considering the performance, this page does not synchronize the modification to the hard disk file immediately after each modification. If you need to force the previous modifications to be synchronized to the corresponding hard disk file at a time, you can use the FlushViewOfFile function to achieve this purpose:

BOOL FlushViewOfFile (PVOID pvAddress, SIZE_T dwNumberOfBytesToFlush );

This function imports the starting address and size of the memory block synchronized to the hard disk file.

(5) cancel the ing from the file content to the virtual address space of the process.

When the access to the file content mapped to the memory is completed and no access is required, the memory of this segment should be reclaimed in time to effectively use system resources. At this time, the UnmapViewOfFile function is called:

BOOL UnmapViewOfFile (PVOID pvBaseAddress );

This function is used to pass in the pointer returned by the MapViewOfFile function. The system recycles the virtual memory address space area reserved and submitted during the corresponding MapViewOfFile call, so that this area can be used by other applications. In addition, because the corresponding backup storage is not a page file of the system, there is no backup storage recovery problem.

(6) disable file ing kernel objects and file kernel objects.

Finally, when the completed task no longer uses this file, the CloseHandle (hFile) and CloseHandle (hMapping) are used to close the file and release the kernel object handle of the memory ing file.

Next we will discuss how to use the memory ing file kernel object to share memory between processes.

When a memory ing file is used between processes for Memory Sharing, the kernel object of the memory ing file is often not based on a hard disk file, instead, it opens up space from the page file of the system as a temporary shared storage space. Therefore, it is slightly different from accessing hard disk files by using memory ing files. The following describes how to share memory between processes through memory ing files. Suppose process A and process B exist. process A creates A memory mem ing file kernel object named "SharedMem" based on the system paging file through CreateFileMapping:

HANDLE m_hFileMapA = CreateFileMapping

(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0,

10*1024, TEXT ("SharedMem "));

Note that because it is no longer based on common hard disk files, you do not need to call CreateFile to create or open a file. Note that the input file handle parameter is INVALID_HANDLE_VALUE, this parameter indicates that the open space in the page file is used as the shared memory.

Process B uses OpenFileMapping to open the memory ing file kernel object named "SharedMem" created by process:

HANDLE m_hFileMapB = OpenFileMapping (...,TEXT ("SharedMem"));

Process A and process B can use this memory ing file to map all or part of the bucket opened in the system paging file to the memory, and then use it.

Process:

...

PVOID pViewA = MapViewOfFile (m_hFileMapA, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0 );

...

Process B:

...

PVOID pViewB = MapViewOfFile (m_hFileMapB, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0 );

...

Their respective modifications to the shared memory can be seen by the other party in a timely manner. Note that they are mapped to the virtual memory space area andNot necessarily have the same starting addressBecause they have their own virtual address space.

There is another issue that needs attention, but it is difficult to find out because the kernel object of the memory ing file created based on the system page file is marked by passing in the hFile as the INVALID_HANDLE_VALUE parameter, the returned value when a common hard disk file fails to be created or opened is also INVALID_HANDLE_VALUE. Therefore, the bug in the following code is hard to be found:

...

HANDLE hFile = CreateFile (...);

HANDLE hMap = CreateFileMapping (hFile ,...);

If (hMap = NULL)

Return (GetLastError ());

...

The purpose of this Code is to first create or open a common hard disk file, and then create a memory ing file Kernel Object Based on this file, instead of creating a system-based page object. However, when the execution of the first CreateFile statement fails, INVALID_HANDLE_VALUE is returned. The returned value is immediately passed into the CreateFileMapping function, and a memory ing file Kernel Object Based on the system paging file is created. This is not the original intent of this code, but it also causes problems. Because operations on the kernel objects of memory ing files based on common hard disk files often want to save the final results in this file, the operations on the kernel object of the memory ing file based on the system paging file usually focus on the results of the data during the execution period, and the results are not saved after the operation. When CreateFile fails and the program runs, the program runs correctly. However, when checking the result file, you will find that the file is either not created or the data has not been changed, because subsequent operations are based on system paging files!

Therefore, when using a memory ing file kernel object based on a common hard disk file, you must check the return value after calling createfile.

3. Heap

Heap functions, such as linked list nodes and Tree nodes, are generally used to allocate multiple small pieces of memory. The biggest advantage of heap functions is that developers do not need to consider trivial things such as page boundaries; the disadvantage is that heap function operations are slower than virtual memory and memory ing files, and physical storage cannot be directly submitted or recycled just like virtual memory or memory ing files.

Each process has a default heap, and its initial region size is 1 MB by default. You can modify this default value through the/heap parameter when linking. The temporary storage of many operations uses the default heap of the process. For example, for the vast majority of Win32 functions, the handle of the default heap of the process can be obtained through the getprocessheap function.

Because most of the program's memory needs are allocated from the default heap of the process, and thread security needs to be considered in the case of multithreading. Therefore, for specific applications, this situation may cause program performance degradation. To address this requirement, Win32 provides a custom heap mechanism.

Follow these steps to create a custom heap.

(1) create a custom heap.

Unlike the default process heap (which is automatically created when a process is created), you must first create a custom heap using the heapcreate function:

Handle heapcreate (

DWORD fdwoptions,

Size_t dwinitialsize,

Size_t dwmaximumsize );

The fdwoptions parameter specifies whether serial access is required (HEAP_NO_SERIALIZE), And whether to throw an exception (heap_generate_exceptions) When memory allocation and recovery errors occur ). When the custom heap is accessed by multiple threads at the same time, support for serial access is required, but the corresponding performance will decrease.

The dwInitialSize parameter specifies the size of the storage submitted when the custom heap is created (a multiple of the page size), and the dwMaximumSize parameter specifies the size of the pre-set area of the custom heap from the virtual address space of the process. With the allocation of the custom heap memory, the size of the submitted storage increases, but this parameter limits the limit of increase. In another case, dwMaximumSize is 0, and the custom heap can continue to grow until the virtual address space of the process is used up.

(2) allocate memory from the custom heap.

The HeapAlloc function is called to allocate memory from the custom heap (this function is also called to allocate memory from the default heap of the Process ):

PVOID HeapAlloc (

HANDLE hHeap,

DWORD fdwFlags,

SIZE_T dwBytes );

The hHeap parameter is the HEAP kernel object handle returned in the previous step. The fdwFlags parameter can have three values, HEAP _ ZERO_MEMORY, HEAP_GENERATE_EXCEPTIONS, and HEAP_NO_SERIALIZE. The HEAP_ZERO_MEMORY parameter indicates that all. HEAP_GENERATE _ EXCEPTIONS indicates that if the memory allocation fails, an exception must be thrown. If this parameter is specified when a custom heap is created, you do not need to specify this parameter for memory allocation on it. If this parameter is not specified During Heap creation, you can specify this parameter at each application. The HEAP_NO_SERIALIZE parameter indicates that the allocation does not require serialized access. The final dwBytes parameter specifies the size of the memory allocated this time. The returned value is the starting position of the memory allocated.

(3) release the memory.

Call the HeapFree function to release memory from the heap:

BOOL HeapFree (

HANDLE hHeap,

DWORD fdwFlags,

PVOID pvMem );

The parameters of this function are significant and need not be described in detail. It should be pointed out that releasing the memory does not guarantee that all physical storage is recycled. First, physical storage determines whether it can be recycled Based on the page size; second, consider the efficiency when designing the heap mechanism for Windows.

(4) destroy the custom heap.

When the program no longer needs to use a custom heap, call the HeapDestroy function:

BOOL HeapDestroy (HANDLE hHeap );

The first is that when the heap is destroyed, all memory allocated from the heap is recycled instead of being released one by one, at the same time, the physical storage and virtual address space occupied by the heap will be recycled by the system. Second, if the custom heap is not explicitly destroyed, the heap will be destroyed by the system when the program exits. It should be noted that the custom heap created by the thread will not be destroyed when the thread exits, but will be destroyed only when the whole process exits. From the perspective of resource utilization efficiency, the user-defined heap should be destroyed immediately when it is no longer in use. Third, the process's default heap cannot be destroyed through this function. More strictly speaking, the process's default heap cannot be destroyed before the process exits.

Other functions of the custom heap are as follows.

(1) obtain all the processes:

DWORD GetProcessHeaps (

DWORD dwNumHeaps,

PHANDLE pHeaps );

This function returns all the current heap (including the default heap of the process) of the process, an array containing the handle of all heap kernel objects, and the size of the array. the return value is the number of heap.

(2) modify the size of the allocated memory:

PVOID HeapReAlloc (

HANDLE hHeap,

DWORD fdwFlags,

PVOID pvMem,

SIZE_T dwBytes );

This function can modify the size of the originally allocated memory block (pvMem). The new size is specified by the dwBytes parameter.

(3) query the size of allocated memory of a block:

SIZE_T HeapSize (

HANDLE hHeap,

DWORD fdwFlags,

LPCVOID pvMem );

This function can query the size of a previously allocated memory block. When the memory block pointer is passed in by an external module, this function can be used if you need to know the exact size of the block.

(4) Heap compression:

UINT HeapCompact (

HANDLE hHeap,

DWORD fdwFlags );

This function combines adjacent free blocks recycled together. Note that this function cannot move allocated memory blocks, that is, it cannot eliminate memory fragments.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.