You create a discardable memory object by combining the GMEM_DISCARDABLE and GMEM_MOVEABLE constants when allocating the object. The resulting object will be moved as necessary to make room for other allocation requests, or if there is not enough memory to satisfy the request, the object may be discarded. The following example allocates a discardable object from global memory:
hMem = GlobalAlloc(GMEM_MOVEABLE | GMEM_DISCARDABLE, 4096L);
When Windows discards a memory object, it empties the object by reallocating it, with zero bytes given as the new size. The contents of the object are lost, but the memory handle of the object remains valid. Any attempt to lock the handle and access the object will fail, however.
Windows determines which memory objects to discard by using a least-recently-used (LRU) algorithm. It continues to discard memory objects until there is enough memory to satisfy an allocation request. In general, if you have not accessed a discardable object in some time, it is a candidate for discarding. A locked object cannot be discarded.
You can discard your own memory objects by using the GlobalDiscard function. This function empties the object but preserves the memory handle. You can also discard other applications' memory objects by using the GlobalCompact function. This function moves and discards memory objects until the specified or largest possible amount of memory is available. One way to discard all discardable objects is to supply –1 as the argument. This is a request for every byte of memory. Although the request will fail, it will discard all discardable objects and leave the largest possible free memory object.
Since a discarded memory object's handle remains valid, you can still retrieve
information about the object by using the GlobalFlags function. This is
useful for verifying that the object has been discarded. GlobalFlags sets the GMEM_DISCARDED bit in its return value when the specified memory object has been discarded. Therefore, if you attempt to lock a discardable object and the lock fails, you can check the object's status by using GlobalFlags.
Once a discardable object has been discarded, its contents are lost. If you want to use the object again, you must reallocate it to its appropriate size and fill it with the data it previously contained. You can reallocate it by using the GlobalReAlloc function. The following example checks the object's status, and then fills it with data if it has been discarded:
lpMem = GlobalLock(hMem);
if (lpMem == NULL) {
if (GlobalFlags(hMem) & GMEM_DISCARDED) {
hMem = GlobalReAlloc(hMem, 4096L,
GMEM_MOVEABLE | GMEM_DISCARDABLE);
lpMem = GlobalLock(hMem);
/* More program lines.... */
/* Fill with data. */
GlobalUnlock(hMem);
}
}
You can make a discardable object nondiscardable (or vice versa) by using the GlobalReAlloc function and the GMEM_MODIFY constant. The following example changes a movable object, identified by the hMem memory handle, to a movable, discardable object:
hMem = GlobalReAlloc(hMem, 0, GMEM_MODIFY | GMEM_DISCARDABLE);
The following example changes a discardable object to a nondiscardable one:
hMem = GlobalReAlloc(hMem, 0, GMEM_MODIFY);
When you specify GMEM_MODIFY in a call to the GlobalReAlloc function, the second parameter is ignored.