Using Discardable Global Memory

Discardable memory segments are generally used for data that can be easily regenerated. For example, suppose you decide to use a separate file for ”help“ text that your program displays when the user requests it. You could allocate a moveable block, lock it, read some data from the file, display it on the screen, unlock the block, and free it. However, this approach requires that your program allocate a new block of memory and access this file every time help information is requested.

Alternatively, you could keep a moveable block for this file buffer in memory all the time. When the user requests some help information, you check to see that the information is already in the buffer, and then you use that information rather than access the disk again. The performance of your program improves, but it does so at the cost of having a block of global memory allocated for the duration of your program.

How about using a discardable block instead? This keeps the buffer in memory but also gives Windows permission to discard it if necessary. When you lock the block:

lpGlobalMemory = GlobalLock (hGlobalMemory) ;

the lpGlobalMemory return value will be NULL if the block has been discarded. In that case, you use GlobalReAlloc to reallocate the segment. Windows never discards a discardable block when the lock count is nonzero.

If you have obtained a valid far pointer from GlobalLock, that pointer is valid until you call GlobalUnlock. Even after the block is discarded, the handle is still valid. (This avoids problems when you pass the handle to GlobalLock.)

You can also determine that a block is discardable or has been discarded by using the GlobalFlags function:

wFlags = GlobalFlags (hGlobalMemory) ;

WINDOWS.H has identifiers you can use in combination with wFlags. This value is nonzero if the block is discardable:

(GMEM_DISCARDABLE & wFlags)

This value is nonzero if the block has been discarded:

(GMEM_DISCARDED & wFlags)

Another approach is to include the GLOBAL_NOTIFY flag when allocating a discardable segment. In this case, Windows will call a call-back function in your program that has been registered with the GlobalNotify function when it is about to discard a discardable segment.