views:

463

answers:

4

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?

+3  A: 

same answer as here: http://stackoverflow.com/questions/1588922/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.

Tobias Langner
These are great ways for minimizing fragmentation, but not for working it around.
sharptooth
What do you mean by work around?
GMan
I assume sharptooth asks what to do in case his program detects heap fragmentation.
Nick D
Yeap, exactly. One strategy is just restart periodically. What else could I do?
sharptooth
prevent the heap fragmentation. Else: free as much memory as you can and then reallocate. Try to free memory regions close together.
Tobias Langner
A: 

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.

Robert Christie
+3  A: 

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.

Totonga
VMMap is a great find. Thanks.
Stuart
A: 

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.

MSalters
This is how Apple's Mac was able to run a whole Windowed Operating system and Application in 128k of ram. This would seem impossible today.
Tony Lambert