%
% "@(#)sag:$Id$"
%

%--------------------------------------------------------------------
\chapter{Memory Management} \label{chap:mem}
%--------------------------------------------------------------------

        \begin{raggedleft}
        \it
Minnet, jag har tappat mitt minne, \\
\"ar jag svensk eller finne \\
kommer inte ih\aa g\dots \\
 \ \\
Inne, \"ar jag ute eller inne \\
jag har luckor i minnet, \\
s\aa d\"ar sm\aa\ ALKO-H\AA L \\
Men besinne, \\
man t\"atar med det br\"annvin man f\aa r, \\
fast\"an minnet och helan g\aa r. \\
 \ \\
(Bosse \"Osterberg) \\
        \end{raggedleft}
        \vspace{2em}

	\noindent
	This section describes the Linux memory management features,
	i.e., virtual memory and the disk buffer cache.  The purpose and
	workings and the things the system administrator needs to take
	into consideration are described.

\section{What is virtual memory?}

	Linux supports \defin{virtual memory}, that is, using a 
	disk as an extension of RAM so that the effective size of
	usable memory grows correspondingly.  The kernel will write
	the contents of a currently unused block of memory to the
	hard disk so that the memory can be used for another purpose.
	When the original contents are needed again, they are read
	back into memory.  This is
	all made completely transparent to the user; programs running under
	Linux only see the larger amount of memory available and
	don't notice that parts of them reside on the disk from
	time to time.  Of course, reading and writing the hard disk is
	slower (on the order of a thousand times slower) than using
	real memory, so the programs don't run as fast.  The part of
	the hard disk that is used as virtual memory
	is called the \defin{swap space}.

	Linux can use either a normal file in the filesystem or a
	separate partition for swap space.  A swap partition is
	faster, but it is easier to change the size of a swap file
	(there's no need to repartition the whole hard disk, and
	possibly install everything from scratch).  When you know how
	much swap space you need, you should go for a swap partition,
	but if you are uncertain, you can use a swap file first, use
	the system for a while so that you can get a feel for how much
	swap you need, and then make a swap partition when you're
	confident about its size.

	You should also know that Linux allows one to use several swap
	partitions and/or swap files at the same time.  This means
	that if you only occasionally need an unusual amount of swap space,
	you can set up an extra swap file at such times, instead of
	keeping the whole amount allocated all the time.

\section{Creating a swap area}

	A swap file is an ordinary file; it is in no way special to
	the kernel.  The only thing that matters to the kernel is that
	it has no holes, and that it is prepared for use with
	\cmd{mkswap(8)}.  It must reside on a local disk, however; it
	can't reside in a filesystem that has been mounted over NFS.
	% \meta explain why not nfs

	The bit about holes is important. The swap file 
	reserves the disk space so that the kernel can quickly swap out
	a page without having to go through all the things
	that are necessary when allocating a disk sector to a file.
	The kernel merely uses any sectors that have already been
	allocated to the file.  Because a hole in a file means that
	there are no disk sectors allocated (for that place in the
	file), it is not good for the kernel to try to use them.

	One good way to create the swap file without holes is through
	the following command:
		%
		\begin{tscreen}
\verb|ttyp5 root ~ $| {\sl dd if=/dev/zero of=/extra-swap bs=1024 count=1024}\\
\verb|1024+0 records in| \\
\verb|1024+0 records out| \\
\verb|ttyp5 root ~ $ |
		\end{tscreen}
		%
	where \fn{/extra-swap} is the name of the swap file and 
	the size of is given after the \texttt{count=}.  It is best for
	the size to be a multiple of 4, because the kernel writes out
	\defin{memory pages}, which are 4 kilobytes in size.  If the
	size is not a multiple of 4, the last couple of kilobytes may
	be unused.

	A swap partition is also not special in any way.  You create it
	just like any other partition; the only difference is that it is
	used as a raw partition, that is, it will not contain any
	filesystem at all.  It is a good idea to mark swap partitions as
	type 82 (Linux swap); this will the make partition listings
	clearer, even though it is not strictly necessary to the kernel.

	After you have created a swap file or a swap partition, you
	need to write a signature to its beginning; this contains some
	administrative information and is used by the kernel.  The
	command to do this is \cmd{mkswap(8)}, used like this:
		%
		\begin{tscreen}
\verb|ttyp5 root ~ $| {\sl mkswap /extra-swap 1024} \\
\verb|Setting up swapspace, size = 1044480 bytes| \\
\verb|ttyp5 root ~ $ |
		\end{tscreen}
		%
	Note that the swap space is still not in use yet: it
	exists, but the kernel does not use it to provide virtual
	memory.

	The Linux memory manager limits the size of each swap area to
	127.5~MB.  A larger swap space can be created, but only the
	first 127.5~MB are actually used.  You can, however, use up to
	16 swap spaces simultaneously, for a total of almost
	2~GB.\footnote{A gigabyte here, a gigabyte there, pretty soon
	we start talking about real memory.}

\section{Using a swap area}

	An initialized swap area is taken into use with \cmd{swapon(8)}.
	This command tells the kernel that the swap
	area can be used.  The path to the swap area is given as
	the argument, so to start swapping on a temporary swap
	file one might use the following command.
		%
		\begin{tscreen}
		swapon /usr/tmp/temporary-swap-file
\verb|ttyp5 root ~ $| {\sl swapon /extra-swap} \\
\verb|ttyp5 root ~ $|
		\end{tscreen}
		%
	Swap areas can be used automatically by listing them in
	the \fn{/etc/fstab} file.
		%
		\begin{tscreen}
/dev/hda8        swap        swap        defaults
		\end{tscreen}
		%
	The startup scripts will run
	the command \cmd{swapon -a}, which will start swapping on
	all the swap areas listed in \fn{/etc/fstab}.  Therefore,
	the \cmd{swapon} command is usually used only when extra swap 
	is needed.

	You can monitor the use of swap areas with \cmd{free(1)}.
	It will tell the total amount of swap space used.
	The same information is available via \cmd{top(1)},
	or using the \texttt{proc} filesystem in file \fn{/proc/meminfo}.
	It is
	currently difficult to get information on the use of a specific
	swap area.

	A swap area can be removed from use with \cmd{swapoff(8)}.
	It is usually not necessary to do it, except for temporary
	swap areas.
	Any pages in use in the swap area are swapped in first; if
	there is not sufficient physical memory to hold them, they will
	then be swapped out (to some other swap area).  
	If there is not enough virtual memory to hold all of the pages
	Linux will start to trash; after a long while it should
	recover, but meanwhile the system is unusable.  You should
	check (e.g., with \cmd{free}) that there is enough free
	memory before removing a swap space from use.

	All the swap areas that are used automatically with
	\cmd{swapon -a} can be removed from use with \cmd{swapoff -a};
	it looks at the file \fn{/etc/fstab} to find what to remove.
	Any manually used swap areas will remain in use.

	Sometimes a lot of swap space can be in use even though there
	is a lot of free physical memory.  This can happen for instance
	if at one point there is need to swap, but later a big process
	that occupied much of the physical memory terminates and
	frees the memory.  The swapped-out data is not
	automatically swapped in until it is needed, so the physical
	memory may remain free for a long time.  There is no need to
	worry about this, but it can be comforting to know what is
	happening.

\section{Sharing swap areas with other operating systems}

	Virtual memory is built into many operating systems.  Since they
	each need it only when they are running, i.e., never at the same
	time, the swap areas of all but the currently running one are being
	wasted.  It would be more efficient for them to share a single
	swap area.  This is possible, but can require a bit of hacking.
	The Tips-HOWTO contains some advice on how to implement this.

\section{Allocating swap space} \label{sec:swap-alloc}

	Some people will tell you that you should allocate twice as much
	swap space as you have physical memory, but this is a bogus rule.
	Here's how to do it properly:

    \begin{enumerate}

    \item

	Estimate your total memory needs.  This is the largest amount of
	memory you'll probably need at a time, that is the sum of the
	memory requirements of all the programs you want to run at the
	same time.  This can be done by running at the same time all the
	programs you are likely to ever be running at the same time.

	For instance, if you want to run X, you should
	allocate about 8 MB for it, gcc wants several megabytes (some
	files need an unusually large amount, up to several tens of
	megabytes, but usually about four should do), and so on.  The
	kernel will use about a megabyte by itself, and the usual
	shells and other small utilities perhaps a few hundred
	kilobytes (say a megabyte together).  There is no need to try to be
	exact, rough estimates are fine, but you might want to be on
	the pessimistic side.  Remember that if there are going to be
	several people using the system at the same time, they are all
	going to consume memory.  (However, if two people run the same
	program at the same time, the total memory consumption is
	usually not double, since code pages and shared libraries
	exist only once.)  The \cmd{free(8)} and \cmd{ps(1)} commands
	are useful for estimating the memory needs.

    \item

	Add some security to the estimate in step 1.  This is because
	estimates of program sizes will probably be wrong, because
	you'll probably forget some programs you want to run, and to
	make certain that you have some extra space just in case.  A
	couple of megabytes should be fine.  (It is better to allocate
	too much than too little swap space, but there's no need to
	over-do it and allocate the whole disk, since unused swap space
	is wasted space; see later about adding more swap.)  Also,
	since it is nicer to deal with even numbers, you can round the
	value up to the next full megabyte.

    \item

	Based on the computations in steps 1 and 2, you know how much
	memory you'll be needing in total.  So, in order to allocate
	swap space, you just need to subtract the size of your
	physical memory from the total memory needed, and you know how
	much swap space you need.  (On some versions of UNIX, you
	need to allocate space for an image of the physical memory as
	well, so the amount computed in step 2 is what you need and you
	shouldn't do the subtraction.)

    \item

	If your calculated swap area is very much larger than your
	physical memory (more than a couple times larger), you should
	probably invest in more physical memory, otherwise performance
	will be too low.

    \end{enumerate}

\section{The buffer cache}

	Reading from a disk\footnote{Except a RAM disk, for obvious
	reasons.} is very slow compared to accessing (real) memory.
	In addition, it is common to read the same part of a disk
	several times during relatively short periods of time.  For
	example, one might first read an e-mail message, then read the
	letter into an editor when replying to it, then make the mail
	program read it again when copying it to a folder.  Or,
	consider how often the command \cmd{ls} might be run on a
	system with many users.  By reading the information from disk
	only once and then keeping it in memory until no longer
	needed, one can speed up all but the first read.  This is
	called \defin{disk buffering}, and the memory used for the
	purpose is called the \defin{buffer cache}.

	Since memory is, unfortunately, a finite, nay, scarce resource,
	the buffer
	cache usually cannot be big enough (it can't hold all the data one
	ever wants to use).  When the cache fills up, the data that
	has been unused for the longest time is discarded and the
	memory thus freed is used for the new data.

	Disk buffering works for writes as well.  On the one hand,
	data that is written is often soon read again (e.g., a source
	code file is saved to a file, then read by the compiler), so
	putting data that is written in the cache is a good idea.  On
	the other hand, by only putting the data into the cache, not
	writing it to disk at once, the program that writes runs
	quicker.  The writes can then be done in the background,
	without slowing down the other programs.

	Most operating systems have buffer caches (although they might
	be called something else), but not all of them work according
	to the above principles.  Some are \defin{write-through}: the
	data is written to disk at once (it is kept in the
	cache as well, of course).  The cache is called 
	\defin{write-back} if the writes are done at a later time.
	Write-back is more efficient than write-through, but also a
	bit more prone to errors: if the machine crashes, or the power
	is cut at a bad moment, or the floppy is removed from the disk
	drive before the data in the cache waiting to be written gets
	written, the changes in the cache are usually lost.  This
	might even mean that the filesystem  (if there is one)
	is not in full working order, perhaps because the unwritten
	data held important changes to the bookkeeping information.
	Because of this, you should never turn off the power without
	using a proper shutdown procedure (see an as yet unwritten
	chapter), or remove a floppy from the disk drive until it
	has been unmounted (if it was mounted) or after whatever program
	is using it has signaled that it is finished and the floppy drive
	light doesn't shine anymore.  The \cmd{sync(8)} command \defin{flushes}
	the buffer, i.e., forces all unwritten data to be written
	to disk, and can be used when one wants to be sure that everything
	is safely written.  In traditional UNIX systems, there is a
	program running in the background which does a sync every
	30~seconds, so it is usually not necessary to use \cmd{sync}.
	Linux has an additional daemon, \cmd{bdflush(8)}, that
	does a more imperfect sync more frequently to avoid the sudden
	freeze due to heavy disk I/O that \cmd{sync} sometimes causes.

	The cache does not actually buffer files, but blocks, which are
	the smallest units of disk I/O (under Linux, they are usually
	1~kB).  This way, also directories, super blocks, other
	filesystem bookkeeping data, and non-filesystem disks are
	cached.

	The effectiveness of a cache is primarily decided by its size.
	A small cache is next to useless: it will hold so little data
	that all all cached data is flushed from the cache before it
	is reused.  The critical size depends on how much data is read
	and written, and how often the same data is accessed.  The
	only way to know is to experiment.

	If the cache is of a fixed size, it is not very good to have
	it too big, either, because that might make the free memory
	too small and cause swapping (which is also slow).  To make
	the most efficient use of real memory, Linux automatically
	uses all free RAM for buffer cache, but also automatically
	makes the cache smaller when programs need more memory.

	Under Linux, you do not need to do anything to make use of
	the cache, it happens completely automatically.  Except for
	following the proper procedures for shutdown and removing
	floppies, you do not need to worry about it.
