Welcome to my Blogsite!

http://www.blogsite.psvphil.com

http://aurelie.prepys.com

http://www.ideas.perfectkeys.com

LECTURE 9

Operating Systems - Storage Management (Night Class)

Compiled By Aurelie A. Peralta

The main purpose of a computer system is to execute programs. These programs, together with the data they access, must be in main memory (at least partially) during execution.

To improve both the utilization of the CPU and the speed of its response to users, the computer must keep several processes in memory. Many memory-management schemes exist, reflecting various approaches, and the effectiveness of each algorithm depends on the situation. Selection of a memory-management scheme for a system depends on many factors, especially on the hardware design of the system. Each algorithm requires its own hardware support.

Since main memory is usually too small to accommodate all the data and programs permanently, the computer system must provide secondary storage to back-up main memory. Modern computer systems use disks as the primary on-line storage medium for information (both programs and data). The file system provides the mechanism for on-line storage of and access to both data and programs residing on the disks. A file is a collection of related information defined by its creator. The files are mapped by the operating system onto physical devices. Files are normally organized into directories to ease their use.

Memory Management

The CPU can be shared by a set of processes. As a result of CPU scheduling, we can improve both the utilization of the CPU and the speed of the computer’s response to its users.  To realize this increase in performance, however, we must keep several processes in memory; that is, we must share memory.

Memory is central to the operation of a modern computer system. Memory consists of a large array of words or bytes, each with its own address. The CPU fetches instructions from the memory according to the value of the program counter. These instructions may cause additional loading from and storing to specific memory addresses.

Address Binding

Usually, a program resides on disk as a binary executable file. The program must be brought into memory and placed within a process for it to be executed. Depending on the memory management in use, the process may be moved between disk and memory during execution. The collection of processes on the disk that is waiting to be brought into memory for execution forms the input queue.

The normal procedure is to select one of the processes in the input queue and to load that process into memory. As the process is executed, it accesses instructions and data from memory. Eventually, the process terminates, and its memory space is declared available.

Classically, the binding of instructions and data to memory addresses can be done at any step along the way:

1. Compile time: If you know at compile time where the process will reside in memory, then absolute code can be generated.

2. Load time: If it is not known at compile time where the process will reside in memory, then the computer must generate relocatable code.

3. Execution time: If the process can be moved during execution from one memory segment to another, then binding must be delayed until run time.

Logical- Versus Physical-Address Space

An address generated by the CPU is commonly referred to as a logical address, whereas an address seen by the memory unit - that is, the one loaded into the memory-address register of the memory - is commonly called to as a physical address.

The compile-time and load-time address-binding methods generate identical logical and physical addresses. However, the execution-time address-binding scheme results in differing logical and physical addresses. In this case, we usually refer to the logical address as a virtual address. We use logical address and virtual address interchangeably. The set of all logical addresses generated by a program is a logical-address space; the set of all physical addresses corresponding to these logical addresses is a physical-address space. Thus, in the execution-time address-binding scheme, the logical- and physical-address spaces differ.

Dynamic Loading

To obtain better memory-space utilization, we can use dynamic loading. With dynamic loading, a routine is not loaded until it is called. The advantage of dynamic loading is that an unused routine is never loaded. This method is particularly useful when large amounts of code are needed to handle infrequently occurring cases, such as error routines.

Dynamic Linking and Shared Libraries

The concept of dynamic linking is similar to that of dynamic loading. Rather than loading being postponed until execution time, linking is postponed. This feature is usually used with system libraries, such as language subroutine libraries.

More than one version of a library may be loaded into memory, and each program uses its version information to decide which copy of the library to use. Minor changes retain the same version number, whereas major changes increment the version number. Thus, only programs that are compiled with the new library version are affected by the incompatible changes incorporated in it. Other programs linked before the new library was installed will continue using the older library. This system is also known as shared libraries.

Unlike dynamic loading, dynamic linking generally requires help from the operating system.

Overlays

To enable a process to be larger than the amount of memory allocated to it, we can use overlays. The idea of overlays is to keep in memory only those instructions and data that are needed at any given time. When other instructions are needed, they are loaded into space occupied previously by instructions that are no longer needed.

As in dynamic loading, overlays do not require any special support from the operating system. They can be implemented completely by the user with simple file structures, reading from the files into memory and then jumping to that memory and executing the newly read instructions. The operating system notices only that there is more I/O than usual.

The programmer on the other hand, must design and program the overlay structure properly.

Swapping

A process needs to be in memory to be executed. A process, however, can be swapped temporarily out of memory to a backing store, and then brought back into memory for continued execution.

A variant of this swapping policy is used for priority-based scheduling algorithms. If a higher-priority process arrives and wants service, the memory manager can swap out the lower-priority process so that it can load and execute the higher-priority process. When the higher-priority process finishes, the lower-priority process can be swapped back in and continued. This variant of swapping is sometimes called roll out, roll in.

Swapping requires a backing store. The backing store is commonly a fast disk. It must be large enough to accommodate copies of all memory images for all users, and it must provide direct access to these memory images. The system maintains a ready queue consisting of all processes whose memory images are on the backing store or in memory and are ready to run.

Contiguous Memory Allocation

The main memory must accommodate both the operating system and the various user processes. We therefore need to allocate different parts of the main memory in the most efficient way possible. One method to accomplish this is by using a contiguous memory allocation method.

The memory is usually divided into two partitions: one for the resident operating system, and one for the user processes. We may place the operating system in either low memory or high memory. The major factor affecting this decision is the location of the interrupt vector. Since the interrupt vector is often in low memory, programmers usually place the operating system in low memory as well.

We usually want several user processes to reside in memory at the same time. We therefore need to consider how to allocate available memory to the processes that are in the input queue waiting to be brought into memory. In this contiguous memory allocation, each process is contained in a single contiguous section of memory.

Memory Protection

Memory protection is all about protecting the operating system from user processes, and protecting user processes from one another.

The relocation-register scheme provides an effective way to allow the operating-system size to change dynamically. This flexibility is desirable in many situations. A code that comes and goes as needed is called transient operating-system code.

Memory Allocation

One of the simplest methods for memory allocation is to divide memory into several fixed-sized partitions. Each partition may contain exactly one process. Thus, the degree of multi-programming is bound by the number of partitions.

The operating system keeps a table indicating which parts of memory are available and which are occupied. Initially, all memory is available for user processes, and is considered as one large block of available memory, a hole. When a process arrives and needs memory, we search for a hole large enough for this process. If we find one, we allocate only as much memory as is needed, keeping the rest available to satisfy future requests.

The first-fit, best-fit, and worst-fit strategies are the most common ones used to select a free hole from the set of available holes.

1. First-fit - allocate the first hole that is big enough.

2. Best-fit - allocate te smallest hole that is big enough.

3. Worst-fit - allocate the largest hole.

These algorithms, however, suffer from external fragmentation. As processes are loaded and removed from memory, the free memory space is broken into little pieces.

Fragmentation

Memory fragmentation can be internal as well as external. Internal fragmentation is the memory that is internal to a partition but is not being used. One solution to the problem of external fragmentation is compaction. The goal is to shuffle the memory contents to place all free memory together in one large block. Compaction is not always possible.

Paging

Paging is a memory-management scheme that permits the physical-address space of a process to be noncontiguous. Paging avoids the considerable problem of fitting the varying-sized memory chunks onto the backing store, from which most of the previous memory-management schemes suffered.

Segmentation

Users prefer to view memory as a collection of variable-sized segments, with no necessary ordering among segments. 

Segmentation is a memory-management scheme that supports this user view of memory. A logical-address space is a collection of segments. Each segment has a name and a length.

Summary

Memory-management algorithms for multiprogrammed operating systems rage from the simple single-user system approach to paged segmentation. The greatest determinant of the method used in particular system is the hardware provided. Every memory address generated by the CPU must be checked for legality and possibly mapped to a physical address. the checking cannot be implemented efficiently in software. Hence, we are constrained by the hardware available.

The memory-management algorithms discussed differ in many aspects. In comparing different memory-management strategies, you should use the following considerations:

1. Hardware support

2. Performance

3. Fragmentation - memory waste

4. Relocation - compaction

5. Swapping

6. Sharing

7. Protection

Reference: Operating System Concepts by Silberschatz, Galvin, and Gagne, 2003