If the physical memory of the computer is large enough to hold all the processes, the schemes explained so far will more or less do. But in practice, the total amount of RAM required by all the processes is often much more than can fit in memory. On a typical Windows or Linux system, something like 40-60 processes

Base and limit registers can be used to give each process a separate address space

or more may be started up when the computer is booted. For instance, when a Windows application is installed, it often issues commands so that on subsequent system boots, a process will be started that does nothing except check for updates to the application. Such a process can easily occupy 5-10 MB of memory. Other background processes check for incoming mail, incoming network connections, and many other things. And all this is before the first user program is started. Serious user application programs these days can easily run from 50 to 200 MB and more. As a result, keeping all processes in memory all the time requires a huge amount of memory and cannot be done if there is not enough memory.

Two general approaches to dealing with memory overload have been developed over the years. The simplest strategy, called swapping, consists of bringing in each process in its entirety, running it for a while, then putting it back on the disk. Idle processes are mostly stored on disk, so they do not take up any memory when they are not running (although some of them wake up periodically to do their work, then go to sleep again). The other strategy, called virtual memory, allows programs to run even when they are only partially in main memory. Below we will examine swapping; in "VIRTUAL MEMORY" we will study virtual memory.

The operation of a swapping system is shown in Figure 2. In the beginning, only process A is in memory. Then processes B and C are created or swapped in from disk. In Figure 2(d) A is swapped out to disk. Then D comes in and B goes out. In the end A comes in again. Since A is now at a different location, addresses contained in it must be relocated, either by software when it is swapped in or (more likely) by hardware during program execution. For instance, base and limit registers would work fine here.

Memory allocation changes

When swapping makes multiple holes in memory, it is possible to merge them all into one big one by moving all the processes downward as far as possible. This technique is known as memory compaction. It is normally not done because it requires a lot of CPU time. For example, on a 1-GB machine that can copy 4 bytes in 20 nsec, it would take about 5 sec to compact all of memory.

A point that is worth making concerns how much memory should be allocated for a process when it is created or swapped in. If processes are created with a fixed size that never changes, then the allocation is simple: the operating system allocates exactly what is required, no more and no less.

If, however, processes data segments can grow, for instance, by dynamically allocating memory from a heap, as in many programming languages, a problem arises whenever a process tries to grow. If a hole is adjacent to the process, it can be allocated and the process allowed to grow into the hole. However, if the process is adjacent to another process, the growing process will either have to be moved to a hole in memory large enough for it, or one or more processes will have to be swapped out to create a large enough hole. If a process cannot grow in memory and the swap area on the disk is full, the process will have to suspended until some space is freed up (or it can be killed).

If it is expected that most processes will grow as they run, it is perhaps a good idea to allocate a little extra memory whenever a process is swapped in or moved, to reduce the overhead associated with moving or swapping processes that no longer fit in their allocated memory. However, when swapping processes to disk, only the memory actually in use should be swapped; it is wasteful to swap the extra memory as well. In Figure 3(a) we see a memory configuration in which space for growth has been allocated to two processes.

Allocating space for a growing data segment

If processes can have two growing segments for instance, the data segment being used as a heap for variables that are dynamically  allocated and released and a stack segment for the normal local variables and return addresses - an alternative arrangement suggests itself, namely that of Figure 3(b). In this figure we see that each process demonstrated has a stack at the top of its allocated memory that is growing downward, and a data segment just beyond the program text that is growing upward. The memory between them can be used for either segment. If it runs out, the process will either have to be moved to a hole with enough space, swapped out of memory until a large enough hole can be made, or killed.


physical memory, processes, ram, virtual memory, memory compaction