Memory Management

  Unlike most PC operating systems, modern (since around

1989) Unix systems use very sophisticated memory

management algorithms to make efficient use of memory

resources. This makes the questions "How much memory do

I have?" and "How much memory is being used?" rather

complicated to answer. First you must realize that there are

three different kinds of memory, three different ways they

can be used by the operating system, and three different

ways they can be used by processes.
 
 

Kinds of Memory:

OS Memory Uses: Virtual Memory Uses: The amount of memory available for processes is at least the

size of Swap, minus Kernel. On more modern systems (since

around 1994) it is at least Main plus Swap minus Kernel and

may also include any files via mapping.
 
 

 

Virtual memory is divided up into pages, chunks that are

usually either 4kb or 8kb in size. The memory manager

considers pages to be the atomic unit of memory. For the

best performance, we want each page to be accessible in

Main memory as it is needed by the CPU. When a page is not

needed, it does not matter where it is located.
 
 

The collection of pages which a process is expected to use in

the very near future (usually those pages it has used in the

very near past, see the madvise call) is called its resident set.

(Some OSs consider all the pages currently located in main

memory to be the resident set, even if they aren't being

used.) The process of moving some pages out of main

memory and moving others in, is called swapping. (For the

purposes of this discussion, disk caching activity is included

in this notion of swapping, even though it is generally

considered a separate activity.)
 
 

A page fault occurs when the CPU tries to access a page that

is not in main memory, thus forcing the CPU to wait for the

page to be swapped in. Since moving data to and from disks

takes a significant amount of time, the goal of the memory

manager is to minimize the number of page faults.

Where a page will go when it is "swapped-out" depends on

how it is being used. In general, pages are swapped out as

follows:

 
Kernel
Never swapped out.
Cache
Page is discarded.
Data
Moved to swap space.
Stack
Moved to swap space.
Mapped
Moved to originating file.
It is important to note that swapping itself does not

necessarily slow down the computer. Performance is only

impeded when a page fault occurs. At that time, if memory is

scarce, a page of main memory must be freed for every page

that is needed. If a page that is being swapped out has

changed since it was last written to disk, it can't be freed

from main memory until the changes have been recorded

(either in swap space or a mapped file).
 
 

Writing a page to disk need not wait until a page fault occurs.

Most modern UNIX systems implement preemptive

swapping, in which the contents of changed pages are copied

to disk during times when the disk is otherwise idle. The page

is also kept in main memory so that it can be accessed if

necessary. But, if a page fault occurs, the system can instantly

reclaim the preemptively swapped pages in only the time

needed to read in the new page. This saves a tremendous

amount of time since writing to disk usually takes two to four

times longer than reading. Thus preemptive swapping may

occur even when main memory is plentiful, as a hedge

against future shortages.
 
 

Since it is extremely rare for all (or even most) of the

processes on a UNIX system to be in use at once, most of

virtual memory may be swapped out at any given time

without significantly impeding performance. If the activation

of one process occurs at a time when another is idle, they

simply trade places with minimum impact. Performance is

only significantly affect when more memory is needed at

once than is available. This is discussed more below.
 
 

The subject of file mapping deserves special attention simply

because most people, even experienced programmers, never

have direct experience with it and yet it is integral to the

function of modern operating systems. When a process maps

a file, a segment of its virtual memory is designated as

corresponding to the contents of the given file. Retrieving

data from those memory addresses actually retrieves the

data from the file. Because the retrieval is handled

transparently by the OS, it is typically much faster and more

efficient than the standard file access methods. (See the

manual page mmap and its associated system calls.)
 
 

In general, if multiple processes map and access the same file,

the same real memory and swap pages will be shared among

all the processes. This allows multiple programs to share data

without having to maintain multiple copies in memory.
 
 

The primary use for file mapping is for the loading of

executable code. When a program is executed, one of the

first actions is to map the program executable and all of its

shared libraries into the newly created virtual memory space.

(To see this effect, use trace, truss, or strace, depending on

which UNIX you have, on a simple command like ls and

notice the multiple calls to mmap).
 
 

As the program begins execution, it page faults, forcing the

machine instructions to be loaded into memory as they are

needed. Multiple invocations of the same executable, or

programs which use the same code libraries, will share the

same pages of real memory.
 
 

What happens when a process attempts to change a mapped

page depends upon the particular OS and the parameters of

the mapping. Executable pages are usually mapped

"read-only" so that a segmentation fault occurs if they are

written to. Pages mapped as "shared" will have changes

marked in the shared real memory pages and eventually will

be written back to the file. Those marked as "private" will

have private copies created in swap space as they are

changed and will not be written back to the originating file.
 
 

Some operating systems (such as SunOS 4) always copy the

contents of a mapped file into the swap space. This limits the

quantity of mapped files to the size of swap space, but it

means that if a mapped file is deleted or changed (by means

other than a mapping), the mapping processes will still have a

clean copy. Other operating systems (such as SunOS 5) only

copy privately changed pages into swap space. This allows an

arbitrary quantity of mapped files, but means that deleting or

changing such a file may cause a bus in error in the

processes using it.
 
 

The total real memory is calculated by subtracting the kernel

memory from the amount of RAM. (Utilities like top or yamm

can you show you the total real memory available.) Some of

the rest may be used for caching, but process needs usually

take priority over cached data.
 
 

The total virtual memory depends on the degree to which

processes use mapped files. For data and stack space, the

limitation is the amount of real and swap memory. On some

systems it is simply the amount of swap space, on others it is

the sum of the two. If mapped files are automatically copied

into swap space, then they must also fit into swap memory

making that amount the limiting factor. But if mapped files

act as their own swap area, then there is no practical limit to

the amount of virtual memory that could be mapped onto

them.
 
 

In practice, it is easy and cheap to add arbitrary amounts of

swap space and thus virtual memory. The real limiting factor

on performance will be the amount real memory.
 
 

If no programs were sharing memory or mapping files, you

could just add up their resident sets to get the amount of real

memory in use and their virtual memories to get the amount

of swap space in use. But shared memory (both through

mapped files and IPC system calls) means that the resident

sets of multiple processes may be counting the same real

memory pages more than once. Likewise, mapped files (on

OSs that use them for swapping) will count toward a process'

virtual memory use but won't consume swap space.
 
 

Unfortunately, on most OSs there is no easy way to calculate

how much memory is being used for what. Some utility

programs, like top or yamm, may be able to give you an idea,

but their numbers may not have obvious meaning.
 
 

The only practical measure of the memory in use is relative

to the amount available and its affect on performance. If

there is less memory available than the total resident sets of

all running processes (after accounting for sharing), then the

computer will need to be continuously swapping. This

non-stop disk activity is called thrashing and is an indication

that there are too many active processes or that more

memory is needed. If there is just barely enough memory for

the resident sets but not enough for all virtual memory, then

swapping will occur only when new programs are run or

patterns of user interaction change. If there is more real

memory than virtual memory, then there will be plenty of

extra for disk caching.
 
 

If you are concerned about system memory usage, get a

monitoring program and read the memory mangement

manual pages is the system calls section: intro, brk, mmap,

madvise. Then observe both the monitoring output and listen

for swapping. Remember that other disk activity may be

going on, but swapping activity usualy has a distinct audio

pattern that an experienced user can identify.
 
 

If the monitoring programs show very little free memory and

you hear swapping whenever you switch your interaction

between programs already running, then you may need

more real memory. Remember that the system will use as

much memory as is available for caching, so just a low

available memory count doesn't mean you need more RAM

unless swapping is occuring. If you observe a shortage of

swap space, you may need to add more.
 
 

Before you go out and buy more resources, though, make

sure to check that the processes you are running aren't

consuming more than their share of resources. Proprietary X

servers are notorious for consuming arbitrary amounts of

virtual memory over time and should be restarted daily (or

replaced with the freeware version). Clueless users may be

running huge programs or leaving many processes running

in the background. If you can't teach them to behave,

consider placing resource limits on them via calls to limit in

/etc/csh.login (or other system wide login configuraiton files)

or via system calls to rlimit in a shell wrapper.
 
 

Finally, be aware that some operating systems are much

better than others at managing memory. Proprietary systems

are generally much less efficient than the more modern

freeware systems such as Linux or *BSD.


 
 
 
 

[ back ] | [ next ]





 
 

copyright © 1999 bySMELLY CAT®. All rights reserved.