Operating systems offer some kind of mechanism for (both system and user) software to access memory.
In
the most simple approach, the entire memory of the computer is turned over to
programs. This approach is most common in single tasking systems (only one
program running at a time). Even in this approach, there often will be certain
portions of memory designated for certain purposes (such as low memory
variables, areas for operating system routines, memory mapped hardware, video RAM,
etc.).
With
hardware support for virtual memory, operating systems can give programs the
illusion of having the entire memory to themselves (or even give the illusion
there is more memory than there actually is, using disk space to provide the
extra “memory”), when in reality the operating system is continually moving
programs around in memory and dynamically assigning physical memory as needed.
Even with this approach, it is possible that some virtual memory locations are
mapped to their actual physical addresses (such as for access to low memory
variables, video RAM, or similar areas).
The
task of dividing up the available memory space in both of these approaches is
left to the programmer and the compiler. Many modern languages (including C
and C++) have service routines for
allocating and deallocating blocks of memory.
Some
operating systems go beyond basic flat mapping of memory and provide operating
system routines for allocating and deallocating memory. The Macintosh, for example, has two heaps (a system heap and an
application heap) and an entire set of operating system routines for
allocating, deallocating, and managing blocks of memory. The NeXT
goes even further and creates an object oriented set of services for memory
management.
With
hardware support for segments or demand paging, some operating systems (such as
MVS and OS/2)
provide operating system routines for programs to manage segments or pages of
memory.