Chapter Four - Memory Managment
Chapter Four - Memory Managment
Memory Management
Introduction
The CPU fetches instructions and data of a program from memory; therefore, both the program
and its data must reside in the main (RAM and ROM) memory.
Modern multiprogramming systems are capable of storing more than one program, together with
the data they access, in the main memory.
A fundamental task of the memory management component of an operating system is to
ensure safe execution of programs by providing:
– Sharing of memory
– Memory protection
Storage allocation
Information stored in main memory can be classified in a variety of ways:
• Program (code) and data (variables, constants)
• Read-only (code, constants) and read-write (variables)
• Address (e.g., pointers) or data (other variables); binding (when memory is allocated for the
object): static or dynamic
¾ The compiler, linker, loader and run-time libraries all cooperate to manage this
information.
1
From source to executable code
Translation Execution
Compiler
Linker
Source Object
code code(module) code
data
workspace
Loader
Executable
code(load Main Memory
module)
Secondary
storage
Functions of a linker
A linker collects (if possible) and puts together all the required pieces to form the executable
code.
Issues:
• Relocation
Where to put pieces.
• Cross-reference
where to find pieces.
• Re-organization a.out
new memory layout.
Main () 0X2000
{
main libc int x;
0X0 .....
Main ()
Printf( );
{
0X0 }
int x;
..... Printf(...) Printf() 0X2100
Printf( );} + { = {
0X0 ..... ...}
X= } 0X8800
X=...
2
Functions of a loader
A loader places the executable code in main memory starting at a pre-determined location (base or
start address). This can be done in several ways, depending on hardware architecture:
code code
Main
memory
Direct placement
Memory allocation is trivial. No special relocation is needed, because the user programs are
3
always loaded (one at a time) into the same memory location (absolute loading). The linker
produces the same loading address for every user program.
Examples:
• Early batch monitors
• MS-DOS
max OS(drivers,buffers)
unused
User program
user
Operating system
0
Overlays
A program was organized (by the user) into a tree-like structure of object modules, called
overlays.
The root overlay was always loaded into the memory, whereas the sub trees were (re-)loaded
as needed by simply overlaying existing code.
0.0
Overlay tree Memory snapshots
Partitioning
A simple method to accommodate several programs in memory at the same time (to support
multiprogramming) is partitioning.
In this scheme, the memory is divided into a number of contiguous regions, called partitions.
Two forms of memory partitioning, depending on when and how partitions are created (and
modified), are possible:
• Static partitioning
• Dynamic partitioning
These techniques were used by the IBM OS/360 operating system—MFT (Multiprogramming
with Fixed Number of Tasks) and MVT (Multiprogramming with Variable Number of Tasks.)
4
Static partitioning
Main memory is divided into fixed number of (fixed size) partitions during system generation or
start-up.
Programs are queued to run in the smallest available partition. An executable prepared to run in
one partition may not be able to run in another, without being re-linked. This technique uses
absolute loading.
Dynamic partitioning
Any number of programs can be loaded to memory as long as there is room for each. When a
program is loaded (relocatable loading), it is allocated memory in exact amount as it needs.
Also, the addresses in the program are fixed after loaded, so it cannot move.
The operating system keeps track of each partition (their size and locations in the memory.)
Address translation
In order to provide basic protection among programs sharing the memory, both of the above
partitioning techniques use a hardware capability known as memory address mapping, or
address translation. In its simplest form, this mapping works as follows:
5
Fragmentation
Fragmentation refers to the unused memory that the management system cannot allocate.
• Internal fragmentation
Waste of memory within a partition, caused by the difference between the size of a partition and
the process loaded.
ÆSevere in static (fixed) partitioning schemes.
• External fragmentation
Waste of memory between partitions, caused by scattered non-contiguous free space.
ÆSevere in dynamic (variable size) partitioning schemes.
Compaction is a technique that is used to overcome external fragmentation.
Swapping
The basic idea of swapping is to treat main memory as a ‘ ‘pre-emptable’’ resource.
A high-speed swapping device is used as the backing storage of the pre-empted processes.
Memory protection
The second fundamental task of a memory management system is to protect programs sharing
the memory from each other. This protection also covers the operating system itself.
Dynamic relocation
6
With dynamic relocation, each program-generated address (logical address) is translated to
hardware address (physical address) at runtime for every reference, by a hardware device
known as the memory management unit (MMU).
In principle, this is the same technique used earlier by IBM 360 mainframes.
Each program is loaded into a contiguous region of memory. This region appears to be ‘
‘private’ ’ and the bounds register limits the range of the logical address of each program.
Hardware implementation is cheap and efficient: 2 registers plus an adder and a comparator.
Segmentation
The most important problem with base-and-bounds relocation is that there is only one segment
for each process. A segment is a region of contiguous memory.
Segmentation generalizes the base-and-bounds technique by allowing each process to be split
over several segments.
A segment table holds the base and bounds of each segment. Although the segments may be
scattered in memory, each segment is mapped to a contiguous region.
Additional fields (Read/Write and Shared) in the segment table adds protection and sharing
capabilities to segments.
7
Segmentation—an example
Segment table is inserted into the process control block. Table entries are filled as new
segments are allocated for the process.
The segments are returned to the free segment pool when the process terminates.
Segmentation, as well as the base and bounds approach causes external fragmentation and
requires memory compaction.
An advantage of the approach is that only a segment, instead of a whole process, may be
swapped to make room for the (new) process.
Paging
Physical memory is divided into a number of fixed size blocks, called frames. The logical
memory is also divided into chunks of the same size, called pages.
A page table defines (maps) the base address of pages for each frame in the main memory.
The major goals of paging are to make memory allocation and swapping easier and to reduce
fragmentation.
Paging also allows allocation of non-contiguous memory (i.e., pages need not be adjacent.)
8
Paging—an example
9
Inverted page tables
The inverted page table has one entry for each memory frame. Adv: independent of size of
address space; small table(s).
Hashing is used to speedup table search. Here the inverted page table is system-wide, since the PID is
shown. The Inverted Page Table can also be one per process.
Logical address
Linear address
Physical address
10
Address translation on a Pentium
Associative memory
Problem: Both paging and segmentation schemes introduce extra memory references to access
translation tables.
Solution? Translation buffers.
Based on the notion of locality (at a given time a process is only using a few pages or segments), a very
fast but small associative (content addressable) memory is used to store a few of the translation table
entries. This memory is known as a translation look-aside buffer or TLB.
11
Memory caching
Similar to storing memory addresses in TLBs, frequently used data in main memory can also be
stored in fast buffers, called cache memory, or simply cache. Basically, memory access occurs
as follows:
The idea is to make frequent memory accesses faster!
Cache terminology
Cache hit: item is in the cache.
Cache miss: item is not in the cache; must do a full operation.
Categories of cache miss:
• Compulsory: the first reference will always miss.
• Capacity: non-compulsory misses because of limited cache
size.
Effective access time:
P(hit) * cost of hit + P(miss)* cost of miss
P(miss) = 1 - P(hit)
12
Issues in cache design
Write policy—what if CPU modifies a (cached) location?
This design issue deals with store operations to cached memory locations.
Two basic approaches are:
write through (modify the original memory location as well as the cached data) and
write back (update the memory location only when the cache line is evicted.)
• Block (or line) size—how many words can each line hold?
Studies have shown that a cache line width of 4 to8 addressable units (bytes or words) provide close to
optimal number of hits.
• Number of caches—how many levels? Unified or split cache for data and instructions?
Studies have shown that a second level cache improves performance.
Pentium and Power PC processors each have onchip level-1 (L1) split caches.
Pentium Pro processors have onchip level-2 (L2) cache, as well.
Mapping function
Since there are more main memory blocks (Blocki for i=0 to n) than cache lines (Linej for j=0 to m, and n
>> m), an algorithm is needed for mapping main memory blocks to cache lines.
Direct mapping—maps each block of memory into only one possible cache line. Blocki maps to
Linej, where i = j modulo m.
• Associative mapping—maps any memory block to any line of the cache.
• Set associative mapping—cache lines are grouped into sets and a memory block can be
mapped to any line of a cache set. Blocki maps to Setj where i=j modulo v and v is the number
of sets with k lines each.
13
Dynamic allocation can be handled using either stack (hierarchical, restrictive) or heap (more
general, but less efficient) allocation.
Stack organization
Memory allocation and freeing operations are partially predictable. Since the organization is
hierarchical, the freeing operates in reverse (opposite) order.
Heap organization
Allocation and release of heap space is totally random. Heaps are used for allocation of
arbitrary list structures and complex data organizations. As programs execute (and allocate and
free structures), heap space will fill with holes (unallocated space.)
Analysis of memory allocation strategies indicates that, when a system reaches a steady state
condition, there will be half as many holes as in-use segments in the system. This result is
known as the fifty percent rule.
14
• Linked lists
Another way of keeping track of memory is to maintain a linked list of allocated and free memory
segment. Where a segment is either: - 1- a process or 2- a hole, it can be represented in figure
(c).
Each entry in the list specifies a hole (H) or process (P), the address at which it starts, the
length, and a pointer to the next entry.
A free list keeps track of the unused memory. There are several algorithms that can be used,
depending on the way the unused memory blocks are allocated: first fit, best fit, and worst fit.
First fit- The memory management scans along a list of segments until it finds a hole that is big
enough.
Best fit- It searches the entire list and takes the smallest hole that is adequate.
Worst fit- Always take the largest available hole, so that the hole broken off will be big enough to
be useful.
Reclaiming memory
How do we know when memory can be freed?
It is trivial when a memory block is used by one process. However, this task becomes difficult
when a block is shared (e.g., accessed through pointers) by several processes.
Two problems with reclaiming memory:
• Dangling pointers: occur when the original allocator frees a shared pointer.
• Memory leaks: occur when we forget to free storage, even when it will not or cannot be used
again.
Garbage collection
As an alternative to an explicit free operation, some systems implicitly free storage by simply
deleting pointers. These systems search through all deleted pointers and reclaim the storage
referenced by them.
Some languages, e.g., Lisp and Java, support this kind of “reclaimed” (free) memory
management.
Garbage collection is often expensive; it could use more than 20% of the total CPU time! Also, it
is difficult to code and debug garbage collectors.
15
String word1= “Abebe”;
String word2= “Kebede”;
Thus the two variables have representation
Word1 “Abebe”
Word2 “Kebede”
If the String “Abebe” is deleted, but word1 is still points to the memory location of object
“Abebe”, it is known as dangling reference.
Word1
Word1 “Abebe”
Word2
“Kebede”
Here the String representation of the character String “Abebe” is no longer needed. The
memory for that String object is reclaimed automatically by Java so that it can be used by other
parts of the program. This recycling is known as garbage collection.
16