unit-4_os
unit-4_os
Virtual Memory is a space where large programs can store themselves in form of pages while
their execution and only the required pages or portions of processes are loaded into the main
memory. This technique is useful as a large virtual memory is provided for user programs
when a very small physical memory is there. Thus Virtual memory is a technique that allows
the execution of processes that are not in the physical memory completely.
Virtual Memory mainly gives the illusion of more physical memory than there really is with
the help of Demand Paging.
In real scenarios, most processes never need all their pages at once, for the following
reasons :
Error handling code is not needed unless that specific error occurs, some of which are
quite rare.
Arrays are often over-sized for worst-case scenarios, and only a small fraction of the
arrays are actually used in practice.
In an Operating system, the memory is usually stored in the form of units that are known
as pages. Basically, these are atomic units used to store large programs.
2. Demand Segmentation
Following are the reasons due to which there is a need for Virtual Memory:
In case, if a computer running the Windows operating system needs more memory or
RAM than the memory installed in the system then it uses a small portion of the hard
drive for this purpose.
Suppose there is a situation when your computer does not have space in the physical
memory, then it writes things that it needs to remember into the hard disk in a swap
file and that as virtual memory.
1. Large programs can be written, as the virtual space available is huge compared to
physical memory.
4. Therefore, the Logical address space can be much more larger than that of physical
address space.
6. During the process creation, virtual memory allows: copy-on-write and Memory-
mapped files
Demand paging:
To be simple in demand paging the entire process should be in the disk
in the form of pages
In this technique a page is brought into memory for its execution
only when it is demanded
It is a combination of paging and swapping
Here in the above diagram all the pages are loaded into backing store (hard disk).By the
mechanism of swapping when the main memory requests the page only then it is loaded from
hard disk. As main memory is small in size and cannot handle large programs only few pages
are loaded into main memory after completing its execution it is swapped out simply and new
process is then swapped in.
Basic Concepts :
When a process is to be swapped in, the pager guesses which pages will be used before the
process is swapped out again. Instead of swapping in a whole process, the pager brings only
those pages into memory. Thus, it avoids reading into memory pages that will not be used
anyway, decreasing the swap time and the amount of physical memory needed. With this
scheme, we need some form of hardware support to distinguish between the pages that are in
memory and the pages that are on the disk. The valid–invalid bit scheme can be used for this
purpose. This time, however, when this bit is set to “valid,” the associated page is both legal
and in memory. If the bit is set to “invalid,” the page either is not valid (that is, not in the
logical address space of the process) or is valid but is currently on the disk. The page-table
entry for a page that is brought into memory is set as usual, but the page-table entry for a
page that is not currently in memory is either simply marked invalid or contains the address
of the page on disk.
Marking a page invalid will have no effect if the process never attempts to access that page.
But what happens if the process tries to access a page that was not brought into memory?
Access to a page marked invalid causes a page fault. The paging hardware, in translating the
address through the page table, will notice that the invalid bit is set, causing a trap to the
operating system. This trap is the result of the operating system’s failure to bring the desired
page into memory. The procedure for handling this page fault is straightforward.
1. We check an internal table (usually kept with the process control block) for this process to
determine whether the reference was a valid or an invalid memory access.
2. If the reference was invalid, we terminate the process. If it was valid but we have not yet
brought in that page, we now page it in.
3. We find a free frame (by taking one from the free-frame list, for example).
4. We schedule a disk operation to read the desired page into the newly allocated frame.
5. When the disk read is complete, we modify the internal table kept with the process and the
page table to indicate that the page is now in memory.
6. We restart the instruction that was interrupted by the trap. The process can now access the
page as though it had always been in memory.
In the extreme case, we can start executing a process with no pages in memory. When the
operating system sets the instruction pointer to the first instruction of the process, which is on
a non-memory-resident page, the process immediately faults for the page. After this page is
brought into memory, the process continues to execute, faulting as necessary until every page
that it needs is in memory. At that point, it can execute with no more faults. This scheme is
pure demand paging: never bring a page into memory until it is required.
The hardware to support demand paging is the same as the hardware for paging and
swapping:
• Page table. This table has the ability to mark an entry invalid through a valid– invalid bit or
a special value of protection bits.
• Secondary memory. This memory holds those pages that are not present in main memory.
The secondary memory is usually a high-speed disk. It is known as the swap device, and the
section of disk used for this purpose is known as swap space.
A crucial requirement for demand paging is the ability to restart any instruction after a page
fault. Because we save the state (registers, condition code, instruction counter) of the
interrupted process when the page fault occurs, we must be able to restart the process in
exactly the same place and state, except that the desired page is now in memory and is
accessible. A page fault may occur at any memory reference. If the page fault occurs on the
instruction fetch, we can restart by fetching the instruction again. If a page fault occurs while
we are fetching an operand, we must fetch and decode the instruction again and then fetch the
operand.
Advantages :
Disadvantages:
->Page fault rate increases for bigger programs .
-> If the size of swap file is big it is difficult for main memory
Thrashing
Look at any process that does not have “enough” frames. If the process does not have the
number of frames it needs to support pages in active use, it will quickly page-fault. At this
point, it must replace some page. However, since all its pages are in active use, it must
replace a page that will be needed again right away. Consequently, it quickly faults again,
and again, and again, replacing pages that it must bring back in immediately. This high
paging activity is called thrashing. A process is thrashing if it is spending more time paging
than executing.
Cause of Thrashing :
Thrashing results in severe performance problems.
The operating system monitors CPU utilization. If CPU utilization is too low, we increase
the degree of multiprogramming by introducing a new process to the system. A global page-
replacement algorithm is used; it replaces pages without regard to the process to which they
belong. Now suppose that a process enters a new phase in its execution and needs more
frames. It starts faulting and taking frames away from other processes. These processes need
those pages, however, and so they also fault, taking frames from other processes. These
faulting processes must use the paging device to swap pages in and out. As they queue up
for the paging device, the ready queue empties. As processes wait for the paging device,
CPU utilization decreases. The CPU scheduler sees the decreasing CPU utilization and
increases the degree of multiprogramming as a result. The new process tries to get started by
taking frames from running processes, causing more page faults and a longer queue for the
paging device. As a result, CPU utilization drops even further, and the CPU scheduler tries
to increase the degree of multiprogramming even more. Thrashing has occurred, and system
throughput plunges. The page fault rate increases tremendously. As a result, the effective
memory-access time increases. No work is getting done, because the processes are spending
all their time paging.
This phenomenon is illustrated in Figure, in which CPU utilization is plotted against the
degree of multiprogramming. As the degree of multiprogramming increases, CPU
utilization also increases, although more slowly, until a maximum is reached. If the degree
of multiprogramming is increased even further, thrashing sets in, and CPU utilization drops
sharply. At this point, to increase CPU utilization and stop thrashing, we must decrease the
degree of multiprogramming.
Figure3: Thrashing
We can limit the effects of thrashing by using a local replacement algorithm (or
priority replacement algorithm). With local replacement, if one process starts thrashing, it
cannot steal frames from another process and cause the latter to thrash as well. However, the
problem is not entirely solved. If processes are thrashing, they will be in the queue for the
paging device most of the time. The average service time for a page fault will increase
because of the longer average queue for the paging device. Thus, the effective access time
will increase even for a process that is not thrashing. To prevent thrashing, we must provide
a process with as many frames as it needs.
we can know how many frames it “needs” by several techniques. The working-set strategy
starts by looking at how many frames a process is actually using. This approach defines the
locality model of process execution. The locality model states that, as a process executes, it
moves from locality to locality. A locality is a set of pages that are actively used together. A
program is generally composed of several different localities, which may overlap. For
example, when a function is called, it defines a new locality. In this locality, memory
references are made to the instructions of the function call, its local variables, and a subset
of the global variables. When we exit the function, the process leaves this locality, since the
local variables and instructions of the function are no longer in active use. We may return to
this locality later. we see that localities are defined by the program structure and its data
structures. The locality model states that all programs will exhibit this basic memory
reference structure.
We allocate enough frames to a process to accommodate its current locality. It will fault for
the pages in its locality until all these pages are in memory; then, it will not fault again until
it changes localities. If we do not allocate enough frames to accommodate the size of the
current locality, the process will thrash, since it cannot keep in memory all the pages that it
is actively using.
Page-Fault Frequency:
The working-set model is successful, and knowledge of the working set can be useful for
prepaging , but it seems a clumsy way to control thrashing. A strategy that uses the page-
fault frequency (PFF) takes a more direct approach. The specific problem is how to prevent
thrashing. Thrashing has a high page-fault rate. Thus, we want to control the page-fault rate.
When it is too high, we know that the process needs more frames. Conversely, if the page-
fault rate is too low, then the process may have too many frames. We can establish upper
and lower bounds on the desired page-fault rate. If the actual page-fault rate exceeds the
upper limit, we allocate the process another frame. If the page-fault rate falls below the
lower limit, we remove a frame from the process. Thus, we can directly measure and control
the page-fault rate to prevent thrashing.
Figure: Page table when some pages are not in main
memory