Reducing Fragmentation

Started by
6 comments, last by David Neubelt 16 years, 9 months ago
Anyone have some good ideas to reduce fragmentation. I'm beginning to use the HeapCreate, HeapAlloc, etc API set to separate my memory spaces. Anyone have some useful tips to leverage the capabilities of separated heaps? Thanks!
Advertisement
You're going to have to be a bit more specific. What language? What platform? What are you trying to do?
A general solution is to write a memory manager with pre-allocated different sized buckets of memory pools. You allocate in the smallest possible bucket for your class. The memory manager just uses placement new to allocate you into the first free slot. Other options include having the memory manager reshuffle the memory buckets so free nodes end up at the end of the bucket instead of being interleaved. reshuffling requires that you implement some kind of weak pointer scheme so the manager can move your objects without affecting any pointers your application has.

-me
Effectively reducing the fragmentation has almost nothing to do with custom memory management.

It's about understanding memory usage patterns, then either adjusting your code, or providing custom memory management where needed.

As always, best method to prevent fragmentation and avoid memory problems - do not allocate in the first place.

For everything else, well, allocator-per-type is a rather simple solution, but may have drawbacks (poor memory locality).

Then again - do you have any reason to believe that your code suffers due to memory fragmentation? Solid reason?
I believe that I have fragmentation problems because I can tell how much memory I use as compared to how much is available in my VM space and there is quite a difference. Also, I need my app to stay up on CE devices for several weeks at a time. So, inevitably, I will fragment unless I do something specifically designed to prevent it.

So,
1. I plan to create separate memory spaces. For example, each of my caches will use a separate mem space. Hopefully this will keep like-sized allocations together so I dont inter-leave large and small allocs. Also, I think I can then use HeapDestroy and the re-create the heap to start over from zero frag as fragmentation within each space increases over time. Does this all sound legitimate/accurate/correct?

2. It's difficult to measure fragmentation though - any advice on that?

3. Can someone please give a clear explanation of committed mem vs. reserved mem. Does reserved memory count against my virtual memory space? Does committed only count against my physical memory?

4. Any idea why physical memory available would ever be less than Virtual memory available? Just curious - i observed this on one device.

I am using C++.

I am not interested in writing my own memory mgr, at least for now. Eventually if i need my own mem mgr, perhaps i will pursue later.

Thank you for all advice - much appreciated.
And is there any relationship between virtual memory space and virtual memory?

VM space is on the processor, right?

But Virtual mem is paged out to disk, right?

I just find this confusing - am i missing something here?

Thanks.
I'm not sure but this might be of interest to you.

Windows CE Base Team Blog
Virtual memory isn't always paged out to the disc it is dependent on the architecture, a lot of consoles don't support paging but do support virtual memory. Virtual memory simply means that the address you have in code doesn't represent the address in physical memory.

In the case that your virtual memory is greater then your physical memory then the architecture will support paging. When you allocate more then your physical memory then some memory will have to be swapped and put on disc.

Fragmentation can be easy to view graphically. You can output each mem address allocated and its size and then render a graph. A lot of memory managers will give plenty of statistics. As far as memory managers go, I highly recommend doug lee's memory manager. It's been in the works for around 20 years and has been ported to many different platforms. We use it on all our console games.

Doug Lee's memory manager also supports the concept of memory spaces which I'd recommend to you to use to avoid fragmentation. For each system try to allocate within that systems memory space. If you start getting too much fragmentation in a system then you can shutdown the system, wipe the mem space, and re-initialize the system.

Try to use very minimum of any global memory space. It's very easy to fight fragmentation on a per system level then on a global level. This concept has worked for me very well.

-= Dave

EDIT:

To answer your question on the difference between reserved and committed memory

Reserved memory is like an allocation but you can't use the memory yet. You reserve the memory for future use. Also it is important to note reserved memory wont ever be paged to the disc, and the space reserved for paging wont be created. While committed memory is exactly what you think of when you do a call to alloc. You are saying I want this memory, no one can use it and I'll be using it immediately. This memory will be paged to disc (if the architecture supports paging).
Graphics Programmer - Ready At Dawn Studios

This topic is closed to new replies.

Advertisement