When you run a program, your operating system loads the program into memory and defines an address space in which the program can operate. For example, if your program is executing in a 32-bit computer, the address space is approximately 4 gigabytes.
An operating system does not actually allocate the memory in this address space. Instead, operating systems
memory map this space, which means that the operating system relates the theoretical address space your program could use with what it actually will be using. Typically, operating systems divide memory into pages. When a program begins executing, the operating system creates a map that correlates the executing program with the pages that contain the program’s information.
Figure 1 shows regions of a program where arrows point to the memory pages that contain different portions of your program.
Figure 1 also shows a stack containing three stack frames, each mapped to its own page.
Similarly, the heap shows two allocations, each mapped to its own page. (This figure vastly simplifies actual memory mapping, since a page can have many stack frames and many heap allocations.)
The program did not emerge fully formed into this state. It had to be compiled, linked, and loaded.
Figure 2 shows a program whose source code resides in four files.
Running these files through a compiler creates object files. A linker then merges these object files and any external libraries needed into a load file. This load file is the executable program stored on your computer’s file system.
When the linker creates the load file, it combines the information contained in each of the object files into one unit. Combining them is relatively straightforward. The load file at the bottom of
Figure 2 also details this file’s contents, as this file contains a number of sections and additional information. For example:
The data section contains the my_var1 and
my_var2 variables. In contrast, the memory for the
my_var3 variable is dynamically and automatically allocated and deallocated within the stack by your program’s runtime system.
When the linker creates the load file from the object and library files, it interweaves these sections into one file. The linking operation creates something that your operating system can load into memory.
Figure 3 shows this process.
MemoryScape can provide information about these sections and the amount of memory your program is using. To obtain this information, use the
Memory Reports | Memory Usage and select
Chart report,
Figure 4.