The Big Idea
Primary memory, often called main memory, is the fast, directly accessible storage that a computer uses to hold programs and data while they are being executed. The operating system ensures that each running program is given its own section of memory, preventing conflicts and keeping processes isolated. Within this section, memory is divided into segments that serve different purposes: the text segment, data segment, heap, and stack.
Understanding these divisions is essential because they explain how programs run, how variables are stored, and how function calls are managed.
Operating System and Memory Allocation
When a program is launched:
- The operating system loads it from secondary storage (like a hard drive or SSD) into primary memory (RAM).
- Each program is given a logical view of memory—as if it owns the entire memory space.
In reality, the OS manages the mapping between this logical view and physical RAM, often using techniques like paging or segmentation. - This prevents interference between programs, supports multitasking, and enhances security.
Memory Segments
1. Text Segment (Code Segment)
- Purpose: Stores the compiled machine code instructions of the program.
- Properties:
- Usually marked as read-only, preventing accidental modification of instructions.
- Often shared among processes running the same program to save memory.
- Example: The actual binary instructions for a
forloop or function definition live here.
2. Data Segment
- Purpose: Holds global variables and static variables.
- Subdivided into:
- Initialized data: Variables with explicitly assigned values at program start.
- Uninitialized data (BSS): Variables that are declared but not assigned a value.
Example:
int counter = 0; // stored in initialized data static float pi; // stored in BSS
3. Heap
- Purpose: Stores dynamically allocated memory (requested at runtime).
- Characteristics:
- Grows upward as new memory is requested with functions like
malloc()in C ornewin Java/C++. - Memory must be freed when no longer needed to avoid leaks (in managed languages like Java/Python, garbage collection does this automatically).
- Grows upward as new memory is requested with functions like
- Example: Creating a dynamic array where the size is not known until user input.
4. Stack
- Purpose: Manages function calls and local variables.
- Characteristics:
- Operates in LIFO (Last-In, First-Out) order.
- Stores function parameters, return addresses, and temporary variables.
- Grows downward (opposite direction of the heap).
- Example: Each time a function is called, a new stack frame is pushed, containing the local variables for that call.
Visual Model of Memory Layout
+-------------------+ High memory addresses
| Command-line args |
| Environment vars |
+-------------------+
| Stack | (grows downward)
+-------------------+
| Heap | (grows upward)
+-------------------+
| BSS (uninit.) |
| Data (initialized)|
+-------------------+
| Text (code) |
+-------------------+ Low memory addresses
Why This Matters
- Debugging: Understanding the stack helps when analyzing stack overflow errors.
- Efficiency: Large data structures are best placed on the heap, while small temporaries fit on the stack.
- Security: Many exploits (like buffer overflows) target improper handling of memory in these segments.
Conclusion
Primary memory is more than just “RAM.” It is a carefully managed resource divided into specialized regions that make program execution possible. The operating system ensures fairness and isolation, while the text, data, heap, and stack segments each fulfill unique roles in storing code, global data, dynamic data, and function call information.