It's free to join Gamasutra!|Have a question? Want to know who runs this site? Here you go.|Targeting the game development market with your product or service? Get info on advertising here.||For altering your contact information or changing email subscription preferences.
Registered members can log in here.Back to the home page.

Search articles, jobs, buyers guide, and more.

By Brian Hixon, Daniel Martin, Rob Moore, Greg Schaefer, and Richard Wifall
Gamasutra
[Authors' Bio]
August 2, 2002

Effective Memory Management

Fragmentation Control

Platform Specifics

Printer Friendly Version
   



This feature originally appeared in the February 2002 issue of Game Developer magazine




Game Developer Magazine Back Issues four CD Set.
Every issue 1994 to April 2002.
Price: $189.00 + S&H

Letters to the Editor:
Write a letter
View all letters


Features

Play by Play: Effective Memory Management

Platform Specifics

A memory manager presents a logical view of memory in the same way that a file system provides a logical view of a disk drive. Most often, memory managers are concerned with managing dynamic RAM of some sort. Some console makers like to make things more interesting by providing a relatively large main memory but also scattering other smaller chunks of RAM around the system.

The memory manager allows us to abstract away the physical details of the memory subsystem and deal instead with a nice, logical model of memory. For example, on the PS2 we don’t necessarily need to know that the first megabyte of RAM is reserved for the operating system. It’s enough that the memory manager knows. By abstracting away some of the details of the physical memory system, our game can become more platform independent.

Most console hardware has alignment requirements that, not so surprisingly, differ from platform to platform. Many platforms require anywhere from 4- to 64- byte alignment for buffers in graphics rendering or file IO. Each type of hardware might need the memory manager to be tweaked to better fit the needs and abilities of the platform. Often this information can be passed to the memory manager using a heap setup structure.

Finally, you should be wary of third-party libraries that may use malloc and free , effectively bypassing your memory manager’s interface. The printf function in the PS2 standard C library uses malloc and free ; our solution was to write our own printf function.

Hardware Support

On most modern computers, the issue of fragmentation has been greatly reduced by the use of a hardware-based paged memory manager unit (PMMU).

Obviously, the fact that virtual memory provides an application with lots of addressable memory means that even an inefficient memory manager can be used. However, the more interesting point is that the PMMU without any secondary storage can dramatically help with fragmentation. The PMMU takes a very large address space (larger than the physical RAM it represents) and maps it onto physical memory. Obviously, this mapping is not one-to-one, but rather it maps a subset of the memory space onto a “working set” of memory pages.

The key impact of using a PMMU in terms of fragmentation is that when a memory block is released, any portion of that block completely spanning one or more PMMU pages can be remapped by the PMMU. The result is actually two forms of fragmentation: address-space fragmentation and memory fragmentation. While this effect might seem to make a bad problem worse, it actually simplifies things. Because the PMMU provides a large address space, the address-space fragmentation can be largely ignored. Instead, the allocation algorithm concentrates on minimizing memory fragmentation by first attempting to utilize the unused portions of allocated memory pages (pages that contain some allocation but are not completely full) before remapping unused memory pages back into memory.

Managing Your Memory Manager


Memory managers are like most real-life managers. You have to keep them under control, or else they tend to wander off without adequate information and make strange decisions. Your memory manager sometimes needs your help to stay on the right track too. Let’s look at some common problems that can occur and how to work around them.

Fragged again.One of the major side effects of hand grenades and memory managers is fragmentation. Previously, we discussed fragmentation in the context of designing the memory manager to avoid or reduce the effects of fragmentation. However, there are also some application- level techniques that can reduce fragmentation.

The use of static allocation (memory defined within a module with storage allocated within the application image) avoids the memory manager completely and thus avoids fragmentation. Of course, this usage really only makes sense when a single object will be represented and when the lifetime of that object is approximately the duration of the entire application. In such cases, static allocation can provide a benefit by limiting utilization of the dynamic memory manager to those memory objects that are truly dynamic.

Another strategy that relies entirely on the memory manager user is to perform submanagement of memory based on specific program knowledge. For example, if a module knows that it needs to allocate X objects of size Y, it may be far more efficient for the user to allocate a single block of X * Y bytes and perform its own management within that larger block. By reducing the number of blocks that the memory manager has to deal with, the user has generally made the job of course, a caveat. Depending on the amount of fragmentation and the size of X * Y, it is possible that the application could find itself in the situation where an allocation of X * Y fails due to fragmentation, whereas X allocations of Y would have succeeded. We also try to discourage this practice when possible, as there is code-maintenance overhead.

One way to help avoid memory fragmentation is to always free memory in the opposite order from which it was allocated. In fact, if you were always able to allocate and release in such an order, you would never have memory fragmentation. Realistically, it’s not possible to follow this practice all the time, but doing it as much as possible will help. Memory fragmentation is going to occur, and at some point you will probably run into a situation where it causes a problem in your game. You might have fragmentation that is occurring in one part of your game that is causing a memory allocation to fail in a totally unrelated area. Fragmentation might even manifest itself as a situation where your game will fail only when arriving at part of your game through a specific path (that causes the fragmentation). If you don’t have some advanced form of garbage collection, you are going to have to use other, more crude methods to limit this problem. One possibility is to change the code that is causing the fragmentation to use a different allocator so that it doesn’t cause fragmentation. A common way to accomplish this is to have an allocator that allocates from the other end of memory.

Depending on your game, fragmentation can become more problematic over time (especially if your allocations don’t have close locality of lifespan). You can use brute force to minimize these effects, such as shutting down and restarting code modules between levels as a brute-force garbage collection technique.

Release builds.When running a release build, there isn’t any debugging information in the game, as it will consume extra memory. But you still need a way to know where the game runs out of memory. For Madden, we assume in memory. If the game does run out, it will crash and optionally dump some memory info. With a special build, we display some partial information about the memory manager and the game state so that we can determine if it ran out of memory because of fragmentation or other reasons.

Getting on the Field

When talking about memory management, programmers often resort to words more often associated with cow pastures than games. Terms like heaps, stacks, and chunks are thrown around like flies buzzing around you-know-what. To see how important a memory manager is to a game, you have to get past the abstract poo. A good memory manager allows you to have more animations, more characters, more textures, more sounds — in short, more of everything that your game-playing customers love.

In this article we have described some of the issues that may come up in writing and using your own memory manager. After years of writing and rewriting memory managers for the Madden series, one piece of advice that bears highlighting is simply to make sure you schedule adequate design time on this very important piece of your system; you’ll be glad you did.

References

The Memory Management Reference Beginner’s Guide: www.memorymanagement.org/
articles/begin.html


Johnstone, Mark S., and Paul R. Wilson. “The Memory Fragmentation Problem: Solved?” In Proceedings of the International Symposium on Memory Management.ACM Press, 1998. pp. 26–36. www.cs.utexas.edu/users/wilson/papers/fragsolved.pdf

Knuth, Donald E. The Art of Computer Programming, vol. 1, Fundamental Algorithms. Reading, Mass.: Addison-Wesley, 1973. pp. 435–444.

______________________________________________________
[Back To] Effective Memory Management


join | contact us | advertise | write | my profile
news | features | companies | jobs | resumes | education | product guide | projects | store



Copyright © 2003 CMP Media LLC

privacy policy
| terms of service