In MVS, z/OS, and similar OSes, some
parts of the systems memory are managed in virtual=real
mode, where every virtual address corresponds to a real
address. Those are:
interrupt mechanisms
paging supervisor and page tables
all data buffers accessed by I/O channels
application programs which use non-standard methods
of managing I/O and therefore provide their own buffers
and communicate directly with peripherals (programs that
create their own channel command words).
In IBM's early virtual memory operating
systems virtual=real mode was the only way to "pin down"
pages. z/OS has 3 modes, V=V (virtual=virtual; fully
pageable), V=R and V=F (virtual = fixed, i.e. "pinned down"
but with DAT operating).
Segmented virtual memory
Some systems, such as the Burroughs large
systems, do not use paging to implement virtual memory.
Instead, they use segmentation, so that an application's
virtual address space is divided into variable-length
segments. A virtual address consists of a segment number and
an offset within the segment.
Memory is still physically addressed with
a single number (called absolute or linear
address). To obtain it, the processor looks up the segment
number in a segment table to find a segment descriptor. The
segment descriptor contains a flag indicating whether the
segment is present in main memory and, if it is, the address
in main memory of the beginning of the segment (segment's
base address) and the length of the segment. It checks
whether the offset within the segment is less than the
length of the segment and, if it isn't, an interrupt is
generated. If a segment is not present in main memory, a
hardware interrupt is raised to the operating system, which
may try to read the segment into main memory, or to swap
in. The operating system might have to remove other
segments (swap out) from main memory in order to make
room in main memory for the segment to be read in.
Notably, the Intel 80286 supported a
similar segmentation scheme as an option, but it was unused
by most operating systems.
It is possible to combine segmentation
and paging, usually dividing each segment into pages. In
systems that combine them, such as Multics and the IBM
System/38 and IBM System i machines, virtual memory is
usually implemented with paging, with segmentation used to
provide memory protection. With the Intel 80386 and later
IA-32 processors, the segments reside in a 32-bit linear
paged address space, so segments can be moved into and out
of that linear address space, and pages in that linear
address space can be moved in and out of main memory,
providing two levels of virtual memory; however, few if any
operating systems do so. Instead, they only use paging.
The difference between virtual memory
implementations using pages and using segments is not only
about the memory division with fixed and variable sizes,
respectively. In some systems, e.g. Multics, or later
System/38 and Prime machines, the segmentation was actually
visible to the user processes, as part of the semantics of a
memory model. In other words, instead of a process just
having a memory which looked like a single large vector of
bytes or words, it was more structured. This is different
from using pages, which doesn't change the model visible to
the process. This had important consequences.
A segment wasn't just a "page with a
variable length", or a simple way to lengthen the address
space (as in Intel 80286). In Multics, the segmentation was
a very powerful mechanism that was used to provide a
single-level virtual memory model, in which there was no
differentiation between "process memory" and "file system" -
a process' active address space consisted only a list of
segments (files) which were mapped into its potential
address space, both code and data. It is not the same
as the later mmap function in Unix, because inter-file
pointers don't work when mapping files into semi-arbitrary
places. Multics had such addressing mode built into most
instructions. In other words it could perform relocated
inter-segment references, thus eliminating the need for a
linker completely. This also worked when different processes
mapped the same file into different places in their private
address spaces.
Avoiding thrashing
All implementations need to avoid a
problem called "thrashing", where the computer spends too
much time shuffling blocks of virtual memory between real
memory and disks, and therefore appears to work slower.
Better design of application programs can help, but
ultimately the only cure is to install more real memory. For
more information see Paging.