View
217
Download
1
Tags:
Embed Size (px)
Citation preview
The Memory Fragmentation Problem: Solved?
Mark S. JohnstonePaul R. Wilson
Presented by David Oren ([email protected])
Dynamic Memory Allocation
Memory is Allocated by the running process Freed when no longer needed
The allocator handles those requests, and keeps track of used and unused memory
No garbage collection, no compaction
What Is Fragmentation?
Inefficient use of memory, or…The inability to use free memoryThere are two types of
fragmentation: External fragmentation Internal fragmentation
External Fragmentation
Arises when free blocks are available, but cannot be used to hold objects of the sizes requested
This can have several reasons: The free blocks are too small The allocator is unable to split larger
blocks
Internal Fragmentation
Arises when a block is allocated, but it is larger than needed: the rest is wasted
This can have several reasons: Architecture constraints Allocator policy
Allocator policies
Policies fall into three basic categories: Sequential fits Segregated free lists Buddy systems
Sequential fit
Classic implementations: Doubly linked linear or circular list FIFO, LIFO or address order First, next of best fit
Instances of policiesThere are more efficient
implementations
First fit
Search the list of free blocks from the beginning
Use first large enough block, split if needed
Easy to implement Lots of small blocks at the beginning
Next fit
A common optimization on first fitEach search begins where the
previous one ended No accumulation of small blocks Generally increases fragmentation
Best fit
Use the smallest block large enough Minimize the amount of wasted
space Sequential best-fit is inefficient
Segregated free lists
Use a set of lists of free blocksEach list hold blocks of a given size
A freed block is pushed onto the relevant list
When a block is needed, the relevant list is used
Simple segregated storage
All blocks in the list are of the same size
Large free blocks are not splitSmaller blocks are not coalesced Efficient implementation Internal fragmentation
Segregated fit algorithms
Free list contain several sizesWhen memory is requested
The relevant list is (sequentially) searched
If no block is found, the other lists are searched, and the block is split
Freed blocks are coalesced Approximates best-fit
Buddy systems
Memory is conceptually split into “buddies”
Only “buddies” may be coalesced Very easy coalescing Internal fragmentation
(but may use several buddy-systems to reduce it)
Test Method
Allocators were traditionally tested with synthetically generated allocations
However, we cannot be certain that they resemble real programs
Therefore, the test was conducted using real programs
Test Program Criterions
Allocation intensive programsPrograms with large amount of live
dataA wide variety of program typesAvoiding over-representation of one
typeNon-leaking programs
Test Programs
In the end, eight programs were chosen
They present a variety of different memory usage requirements
It can still be argued whether they are representative of real-life problems
Test Programs
Espressogcc (2.5.1)GhostscriptGrobner
HyperLRUsimP2CPerl
Program Statistics
Program Mem alloc’d Num. objects Live mem Live objects
Espresso 104, 388 1,672,889 263 4,390
GCC 17,972 721,353 2,320 86,872
Ghostscript 48,993 566,542 1,110 15,376
Grobner 3,986 163,310 145 15,376
Hyper 7,378 108,720 2,049 297
LRUsim 1,397 39,103 1,380 39,039
P2C 4,641 194,997 393 12,652
Perl 33,041 1,600,560 69 1,971
Testing Methods
The goal is to test policy, not implementation
The allocators were tested offline, not incorporated into running programs
Runtime was not tested
Testing Methods (Cont.)
Testing was done in three steps: Replacing memory allocation functions with
new ones, which create a trace of calls Reading the trace, and extracting statistics
about the program Reading the trace, and calling the allocation
functions of the policy being tested (keeping track of allocation from the OS)
Removing Overhead
Header and footer overhead Less memory was allocated in the
simulation than the program requestedAlignment overhead
The amount of allocated memory was multiplied by 16
The amount requested from the OS was divided by 16
Defining Fragmentation
There are different definitions of fragmentation
We define it as percentages over and above the amount of live data
Fragmentation can be measured in several ways
Measuring Fragmentation
We have chosen two methods: Maximum amount of memory used by
the allocator, relative to the amount requested by the program, at the point of maximum memory usage
Maximum amount of memory used by the allocator, relative to the maximum amount of live memory
Other Measures
Other measures are also interestingThere is no “right” way to measure
fragmentationFragmentation should be measured
for those conditions under which it is a problem
Experimental Error
Generally, memory was requested from the OS in blocks of 4kb
The measurement of the heap size can be an over-estimate by no more than 4kb
This amount should be divided by 16, yielding 256 bytes
Results
2.3 2.288.04
53.4
73.6
2.23
01020304050607080
Fra
g.
(%)
Strategy
There is a relation between the successful policies They all immediately coalesce memory They reallocate objects that have died
recentlyThis can be called a good strategy
Best fit
Tries to use small free blocksThis gives neighbors of large blocks
time to dieThey are merged into yet larger
blocksWhen a large block is split, it is likely
to be used again
AO first-fit
Allocate blocks from one end of the heap
Blocks at the other end have more time to die and merge into larger blocks
This is obviously not true for next-fit policies
Lifetime
Objects allocated at the same time tend to die at the same time
On average, after 2.5Kb of allocation, 90% of all objects have both neighbors free
It pays to wait a short time after an object is freed
Object size
On average 90% of allocated objects have 6 sizes
Many memory requests are for objects of the same size as freed ones
Good allocators should use this factThere is no reason to increase
internal fragmentation
Conclusions
“…we arrive at the conclusion that the fragmentation problem is a problem of recognizing that good allocation policies already exist, and have inexpensive implementations.”