Heap fragmentation can cause a server application that is expected to run continuously for many months to suddenly start malfunctioning thinking that it's out of memory.
Let's assume that I've done my best to minimize runtime heap fragmentation in my VC++ server application but still it builds up and causes problems. I could for example automatically restart the application every month or every half million requests processed - safely stop it and safely start again with a new heap. What else can I do to workaround heap fragmentation?
same answer as here: How to detect and estimate heap fragmentation in my C++ program?
write your own memory manager adapted to your memory allocation patterns. Or buy one (for example smart-heap).
Since the fragmentation depends on your memory allocation patterns / freeing patterns, a better answer is difficult to give. But you could take a look into fixed size allocators or take a look at the smart heap page how they handle allocation. There are also a lot of papers on this topic. Try for example www.memorymanagement.org
Or you could take a look at FastMM4 - which is open source, but in Pascal/Delphi
There are some programming techniques as well. Most notably: the Object Pool. In this case, there is no fragmentation, as the objects are re-used and not freed. But I think a fixed size allocator performs better than the Object Pool. The Object Pool used this way is only a "poor mans" fixed size allocator.
A good starting point is to enable the low fragmentation heap and check weather it still fragments.
HANDLE heaps[1025];
DWORD nheaps = GetProcessHeaps((sizeof(heaps) / sizeof(HANDLE)) - 1, heaps);
for (DWORD i = 0; i < nheaps; ++i) {
ULONG enableLFH = 2;
HeapSetInformation(heaps[i], HeapCompatibilityInformation, &enableLFH, sizeof(enableLFH));
}
This newly introduced memory manager is switched on by default on Vista/Server 2008 ...
So if you determine that world is better on newer Server OS this might be the reason.
The low fragmentation heap was introduced with a service pack of Windows 2000 but it has to be aktively enabled till Windows Vista.
There is a tool vmmap which gives an overview on memory easy and gives a good overview if fragmentation happens.
Rather than scheduling your restart based on time or number of requests, you could examine the heap to see when the fragmentation has reached a level when the largest contiguous block of memory falls below a certain level - after all - you'll start to see out of memory errors when not when all memory is used up but when you try and allocate objects larger than the size of the biggest free contiguous space in the heap.
You can use VirtualQueryEx to walk your heap and find the largest free contiguous area. For an example of how to do this, see this article.
The obvious workaround is to dig up the old solutions that were invented in the past. For instance, opaque handles to movable objects instead of raw pointers. That allows you to defragment the heap.