| |
|
|
||||
![]() |
||||||
| |
|
|||||
|
Play by Play: Effective Memory Management Fragmentation Control
Memory fragmentation
is a condition that occurs over time as memory is allocated and released
and isolated free blocks form. This is not usually an immediate problem,
but as more fragments form and they get smaller, the opportunity for an
allocation failure due to fragmentation increases. Eventually, if fragmentation
gets severe enough, an allocation may fail because no single free block
is large enough to accommodate the request even though the total amount
of free memory is (Figure 3). Therefore, a good memory manager needs to
either take steps to limit the amount of fragmentation that occurs or
be able to consolidate fragmentation periodically through garbage collection.
An allocation failure is often a lethal error for game code and must be
avoided at all costs. While it is generally fairly easy to determine the
maximum memory required by an application, fragmentation can make such
a calculation meaningless. Allocation policy, free block coalescing and
multiple heaps all play a part in minimizing fragmentation. Free memory
coalescing is a straight-forward technique for limiting fragmentation
that attempts to merge a newly released memory block with its neighbors.
If the block immediately preceding or following the newly released block
is also free, merging the blocks together results in a single, larger
free block. This particular technique is almost mandatory, as without
it, fragmentation occurs very quickly. In addition, this limits the size
of the free list to the minimum number of blocks, which generally has
a positive performance impact on allocation. Since this technique has
no impact on how the memory manager is used externally, it is incorporated
into most memory manager designs.
A technique
that requires more involvement from the memory manager user is to allocate
blocks with similar lifetimes close to each other. If the lifetime of
a memory block is known when it is being allocated, the allocation algorithm
can attempt to place it by other blocks with a similar lifetime. When
these blocks are released, they will be merged into a single large free
block. The problem is that this requires the caller to specify both the
lifetime of each block as well as the total size of the group of blocks
of similar lifetime. As a result, a simpler version of this technique
is usually implemented through the use of multiple heaps. By allocating
blocks with similar lifetimes within their own heap, a similar effect
is achieved, though there are generally practical limitations on the number
of heaps that can be effectively utilized. The debugging
techniques used by the Madden memory manager include the ability
to audit memory usage, collect usage statistics, check for consistency,
and follow the memory map from a debugger. Auditing is really nothing
more than being able to mark a group of blocks when they are allocated
and later check to see if they were all released. Usage statistics, such
as maximum number of allocated and free blocks, as well as maximum allocated
memory, are valuable for evaluating the memory utilization of the application.
With all this information available, you will need to find ways to view that information that can help you when managing your game. A linear list of memory blocks can be useful for spotting potential memory fragmentation, while a list of memory blocks sorted by name can be useful when you have memory leaks. If you do
find a memory block that has leaked, you will know from its name exactly
where the allocation occurred. With group labels you can print out compact
memory maps that show how each conceptual module in your code is using
resources. By tracking this throughout the project, you can easily spot
modules that are using more or less memory than you had budgeted in your
original design. You can also create functions to check whether groups
of memory allocations have been freed. This can help prevent memory leaks
if you know that in certain situations some groups have no allocations.
|
||||||||||||||||||||||||||||
|
|