Memory Management

File mapping provides a way for applications to share memory. It enables applications to view me contents of memory or a file (or a section of a file) as part of their address space, if they have the right name or handle.

A file mapping object is created with CreateFileMapping() , specifying a file handle, which returns a handle to the mapping object. If the file handle QxFFFFFFFF is specified, then the system paging file is used. The file mapping object is referred to by this handle, which is used to map a view of the file . This handle can be inherited by child processes or communicated to other processes to be duplicated. Alternatively, a name can be associated with a file mapping object when it is created. This name can then be used by other processes to obtain a handle to the object.

To implement shared memory, each process must use a handle to the same file mapping object to map a view of the file into its virtual address space. Typically, one process creates the mapping object with

CreateFileMapping() and then maps the object into its own address space using MapViewOfFile() Other processes can then open the file mapping object with OpenFileMapping() specifying a name or using the mapping object file handle, and map the object into their own address space using MapViewOfFile() . Note that the virtual addresses resulting from the mapping in each process can vary, although the physical storage referenced is the same, shareable, memory. This shareable memory is only visible to processes that have mapped it into their address space. Once mapped, memory can be accessed according to specified access rights.

The name used for a file mapping exists in its own name space and will not conflict with other named objects like synchronization objects. It can be NULL for an unnamed file mapping object, and can’t contain the "\" character. If a file mapping object is created from an existing file, created with CreateFile() , then it should be opened with exclusive access , to prevent other processes from accessing the file, and kept open until the memory is finished with.

When a process has finished using a file mapping object, it should unmap it by calling UnmapViewOfFile() which invalidates the shared memory for that process and flushes any changes to the file (if it exists). Flushing to file can be done at any other time by calling FlushViewOfFile(). Note that when flushing a memory-mapped file over a network, FlushViewOfFile() guarantees that the data has been written from the workstation, but not that the data resides on the remote disk. This is because the server may be caching the data on the remote end. Therefore, FlushViewOfFile() may return before the data has been physically written to disk. However, if the file is created with FILE_FLAG_WRITE_THROUGH, the remote file system will not perform lazy writes on the file, and FlushViewOfFile() will return when the actual physical write is complete.

Note also that MapViewOfFile() increments a usage counter that is decremented by

UnmapViewOfFile() or on process termination. The physical named object is not removed from memory until the last process has unmapped the object, and the usage counter is set to zero.

previous page next page