Memory Management: allocation, swapping, and paging
paging
virtual memory hardware
minix memory management
Memory Management: non-virtual memory
a single program in memory can occupy all the space not used
for the OS or the ROM
memory can be shared among a number of tasks using fixed partitions
each executable must be either location-independent code, or
relocatable code relocated at load time
each area of memory must also be protected by matching some bits
kept for each memory area to specific bits in the CPU that user programs
cannot modify
relocation can also be achieved (in hardware) by using two
segment registers, base and limit: on each access,
the CPU checks the address against the limit, then adds the base
for protection, only the OS can change the base and limit registers
Keeping track of memory: pages
memory is divided into fixed-sized units
each unit is allocated or free
two ways to keep track of the allocated/free memory:
bitmap: each bit is 0 if the corresponding page is free, or 1 if
it is taken. For pages of n bits, the bitmap takes up 1/n
of the memory, e.g. for n = 212 bytes = 215 bits
and 4GB = 235 bits of memory, the bitmap takes
221 bits = 218 bytes = 256KB.
linked list: each allocated or free page is stored in a list
which uses the storage of the free segment to keep the "next" pointer.
When a segment is freed, adjacent list entries must be merged, when a
segment is allocated, an existing entry must be changed or split
the linked list algorithm is usable with segments
the bitmap algorithm is usable with segments, but is not a
very good fit
bitmap code to set or test bit n:
char * bitmap;
...
/* set the bit */
bitmap [n / 8] |= 1 << (n % 8);
...
/* test the bit */
if (bitmap [n / 8] | (1 << (n % 8))) {
...
Memory Allocation algorithms for segments
first fit: first free block that fits is split and used. Fast,
fairly good with regard to fragmentation, may waste memory
next fit: same as first fit, but start from the end of the last
search, and wrap around. Almost the same performance as first fit
best fit: search the entire list to find the smallest segment
that will fit. Works great if exact matches are found (i.e. if allocations
are only in a few different sizes), otherwise leaves unusably small holes.
worst fit: use the biggest free block. Makes it hard to ever
allocate large blocks.
quick fit: keep free lists for commonly requested sizes,
use one of the other algorithms for other sizes. Works well much of
the time, makes it expensive to merge segments after deallocation
Memory on Disk
if the OS needs more memory and doesn't have it available, it can
copy something to disk
any process trying to access the memory that is copied to disk
will have to page fault and wait for the OS to bring the bits back
from disk
a process can be swapped to disk in its entirety, and then
it cannot execute. Execution can only resume when the
process is swapped in
or, a process's memory can be divided into fixed-sized pages,
each of which can be written to disk while not in use
when the disk is copied back to memory, it may be in a different
location:
this is easy if an entire segment is copied back in and segment
registers are in use -- only the base register needs to be updated
if pages are used, essentially a segment base register is needed
for each page (since the size is fixed, no limit register is needed)
-- the collection of these "segment base registers" is called the
page table
page tables (one for each process) are kept in memory while any
part of the process is in memory
Paging
the program computes an address and requests the corresponding
virtual memory location
the Memory Management Unit (MMU) is the hardware that
translates the virtual address to a physical address by
reading the page table from memory as needed
the page table entry must contain the physical address of the
page frame corresponding to the given virtual page, and additional
bits to record:
whether the translation is valid (mapped)
whether the page may be written (and/or read or executed)
whether the page has been read (referenced) since this bit was cleared
whether the page has been written (modified, made dirty) since this bit
was cleared
whether the page may be cached (pages corresponding to I/O devices
should not be cached)
dirty pages will have to be written back to disk before being
freed, whereas clean pages can be discarded
pages that already have a copy on disk but are not
dirty can be discarded and, if necessary, re-mapped later
a small associative memory, the Translation Lookaside
Buffer (TLB), caches translations (and other bits) for
recently used pages
some RISC computers require the OS to manage the TLB -- a TLB miss is
handled by the OS, whose pages must always be in the TLB and always in memory
note: formula on p. 409 should be p = root(2se/p)
Efficient Paging
keeping a page table entry for every page of a process's
virtual address space can be expensive
one answer is to keep a top-level page table, and have pointers
to second-level page tables for only those areas that are allocated
another answer is to keep a table of physical-to-virtual address
translations instead: this table takes up a fixed fraction of the
memory (one entry per physical page), and is called an inverted
page table
this efficiency is important as virtual address spaces grow,
e.g. to 64 bits
inverted page tables must be searched (perhaps using hashing)
when a new TLB translation is needed, which suggests software handling
of a page miss