Session 4.1: Memory Management Fundamentals

Understanding memory hierarchy, address spaces, allocation strategies, and the foundation of memory management systems

Module 4 3 Hours Theory & Concepts

Learning Objectives

By the end of this session, you will be able to:
  • Understand the memory hierarchy and its impact on system performance
  • Distinguish between logical and physical address spaces
  • Explain different memory allocation strategies and their trade-offs
  • Understand memory protection and sharing mechanisms
  • Analyze address binding and program loading processes
  • Explain the role and operation of the Memory Management Unit (MMU)
  • Understand dynamic loading and linking concepts
  • Calculate memory utilization and fragmentation metrics
Key Concept

Memory management is the process of controlling and coordinating computer memory, assigning portions called blocks to various running programs to optimize overall system performance. It involves both hardware and software components working together to provide an abstraction of unlimited, fast memory to applications.

Why Memory Management Matters
Performance

Efficient memory usage directly impacts system speed and responsiveness

Protection

Prevents processes from accessing unauthorized memory regions

Sharing

Enables safe sharing of memory between cooperating processes

Abstraction

Provides illusion of large, contiguous memory space to applications

Memory Hierarchy

Computer systems use a memory hierarchy to balance cost, speed, and capacity. Understanding this hierarchy is crucial for effective memory management.

The Memory Pyramid

Memory Hierarchy (Top = Fastest, Bottom = Largest)
CPU Registers
L1 Cache
L2 Cache
L3 Cache
Main Memory (RAM)
Secondary Storage (SSD)
Tertiary Storage (HDD, Tape)

Detailed Memory Characteristics

Memory Type Access Time Typical Size Cost per GB Volatility Management
CPU Registers 0.1-1 ns 32-64 registers Very High Volatile Compiler/CPU
L1 Cache 1-2 ns 16-64 KB Very High Volatile Hardware
L2 Cache 3-10 ns 256 KB - 2 MB High Volatile Hardware
L3 Cache 10-30 ns 4-32 MB High Volatile Hardware
Main Memory (RAM) 50-100 ns 4-128 GB Medium Volatile OS Memory Manager
SSD Storage 0.1-1 ms 256 GB - 8 TB Low Non-volatile File System
HDD Storage 5-20 ms 1-20 TB Very Low Non-volatile File System
Memory Management Focus

Operating system memory management primarily deals with main memory (RAM), which serves as the working space for active processes. The OS must efficiently allocate, protect, and manage this limited but crucial resource.

Performance Impact

Memory Access Time Comparison:
- CPU Register:    1 cycle     (baseline)
- L1 Cache:        3-4 cycles  (3-4x slower)
- L2 Cache:        10-20 cycles (10-20x slower)
- L3 Cache:        30-50 cycles (30-50x slower)
- Main Memory:     200-300 cycles (200-300x slower)
- SSD:             100,000+ cycles (100,000x+ slower)
- HDD:             10,000,000+ cycles (10M+ slower)

Example: If CPU register access = 1 second
- L1 Cache access = 3-4 seconds
- Main Memory access = 3-5 minutes
- SSD access = 1-2 days
- HDD access = 4-6 months

Address Spaces

An address space defines the range of valid addresses that a process can use. Understanding different types of address spaces is fundamental to memory management.

Types of Address Spaces

Logical Address Space
  • Definition: Addresses generated by the CPU during program execution
  • Also called: Virtual addresses
  • Range: 0 to max (determined by CPU architecture)
  • Visibility: Seen by the running program
  • Example: 32-bit system: 0x00000000 to 0xFFFFFFFF
Physical Address Space
  • Definition: Actual addresses in main memory hardware
  • Also called: Real addresses
  • Range: 0 to max physical memory
  • Visibility: Hidden from programs
  • Example: 8GB RAM: 0x00000000 to 0x1FFFFFFFF

Address Space Layout

Typical Process Address Space Layout
Logical Address Space
Stack (High Addresses)
↓ Growing Down
Free Space
↑ Growing Up
Heap (Dynamic)
BSS (Uninitialized)
Data (Initialized)
Text (Code)
0x00000000 (Low Addresses)
Physical Memory Layout
Operating System
Process A
Free Memory
Process B
Free Memory
Process C
Available Space

Address Space Segments Explained

Text Segment
  • Content: Executable code (machine instructions)
  • Properties: Read-only, shareable between processes
  • Size: Fixed at compile time
  • Location: Usually at low addresses
Data Segment
  • Content: Initialized global and static variables
  • Properties: Read-write, process-specific
  • Size: Fixed at compile time
  • Example: int global_var = 42;
BSS Segment
  • Content: Uninitialized global and static variables
  • Properties: Initialized to zero by OS
  • Size: Fixed at compile time
  • Example: int uninitialized_array[1000];
Stack Segment
  • Content: Function calls, local variables, return addresses
  • Properties: LIFO structure, grows downward
  • Size: Dynamic, limited by stack limit
  • Management: Automatic (compiler-generated code)
Heap Segment
  • Content: Dynamically allocated memory (malloc, new)
  • Properties: Grows upward, managed by programmer/runtime
  • Size: Dynamic, limited by available memory
  • Management: Explicit allocation and deallocation

Address Space Example

C Program Example:

#include <stdio.h>
#include <stdlib.h>

int global_initialized = 100;    // Data segment
int global_uninitialized;        // BSS segment
static int static_var = 50;      // Data segment

void function_example() {        // Text segment
    int local_var = 10;          // Stack segment
    static int static_local;     // BSS segment
    
    int *heap_ptr = malloc(sizeof(int) * 100);  // Heap segment
    
    printf("Addresses:\n");
    printf("Code (function): %p\n", function_example);
    printf("Global init: %p\n", &global_initialized);
    printf("Global uninit: %p\n", &global_uninitialized);
    printf("Local var: %p\n", &local_var);
    printf("Heap memory: %p\n", heap_ptr);
    
    free(heap_ptr);
}

Typical Output (addresses will vary):
Code (function): 0x400526
Global init: 0x601040
Global uninit: 0x601044
Local var: 0x7fff5fbff6ac
Heap memory: 0x1c3e010

Analysis:
- Code addresses are low (0x400000 range)
- Global variables in middle (0x601000 range)
- Stack addresses are high (0x7fff... range)
- Heap addresses vary (allocated by memory manager)

Memory Allocation Strategies

Memory allocation determines how the operating system assigns memory blocks to processes. Different strategies have varying trade-offs in terms of efficiency, fragmentation, and implementation complexity.

Contiguous Memory Allocation

Contiguous Allocation

Each process is allocated a single contiguous block of memory. Simple but can lead to fragmentation issues.

1. Fixed Partitioning
Fixed Partition Scheme
Equal-Size Partitions
Operating System
Partition 1 (64KB)
Partition 2 (64KB)
Partition 3 (64KB)
Partition 4 (64KB)
Unequal-Size Partitions
Operating System
Partition 1 (32KB)
Partition 2 (64KB)
Partition 3 (128KB)
Partition 4 (256KB)
Advantages
  • Simple implementation
  • Fast allocation/deallocation
  • No external fragmentation
  • Predictable memory layout
Disadvantages
  • Internal fragmentation
  • Limited number of processes
  • Poor memory utilization
  • Fixed partition sizes
2. Dynamic Partitioning
Variable-Size Partitions

Partitions are created dynamically based on process requirements. Eliminates internal fragmentation but introduces external fragmentation.

Dynamic Allocation Algorithms
First Fit

Strategy: Allocate the first hole that is big enough

Advantage: Fast allocation

Disadvantage: May waste large holes

Algorithm:
1. Start from beginning
2. Find first hole ≥ size
3. Allocate from that hole
4. Split if hole > size

Time: O(n)
Best Fit

Strategy: Allocate the smallest hole that is big enough

Advantage: Minimizes wasted space

Disadvantage: Slower, creates small holes

Algorithm:
1. Search entire list
2. Find smallest hole ≥ size
3. Allocate from that hole
4. Split if necessary

Time: O(n)
Worst Fit

Strategy: Allocate the largest hole

Advantage: Leaves large remaining holes

Disadvantage: Wastes large holes quickly

Algorithm:
1. Search entire list
2. Find largest hole
3. Allocate from that hole
4. Split remaining space

Time: O(n)

Allocation Algorithm Comparison

Example: Memory with holes of sizes [100KB, 500KB, 200KB, 300KB, 600KB]
Request: Allocate 212KB

First Fit:
- Check 100KB: Too small
- Check 500KB: ✓ Fits! Allocate here
- Result: [100KB, 288KB remaining, 200KB, 300KB, 600KB]

Best Fit:
- Check all holes: 100KB(no), 500KB(yes), 200KB(no), 300KB(yes), 600KB(yes)
- Best fit: 300KB (smallest that fits)
- Result: [100KB, 500KB, 200KB, 88KB remaining, 600KB]

Worst Fit:
- Check all holes: 100KB(no), 500KB(yes), 200KB(no), 300KB(yes), 600KB(yes)
- Worst fit: 600KB (largest available)
- Result: [100KB, 500KB, 200KB, 300KB, 388KB remaining]

Performance Analysis:
- First Fit: Fastest allocation, moderate fragmentation
- Best Fit: Slowest allocation, least wasted space per allocation
- Worst Fit: Slow allocation, may preserve large holes longer

Fragmentation Analysis

Internal Fragmentation

Definition: Wasted space within allocated memory blocks

Cause: Allocated block larger than requested

Example: Process needs 18KB, gets 20KB partition → 2KB internal fragmentation

Internal Fragmentation = Allocated Size - Requested Size
External Fragmentation

Definition: Free memory scattered in small, unusable holes

Cause: Allocation and deallocation patterns

Example: Total free space = 50KB, but largest hole = 15KB

External Fragmentation = Total Free - Largest Contiguous Free

Compaction

Memory Compaction

Process of moving allocated blocks to eliminate external fragmentation

Memory Compaction Process
Before Compaction
OS (100KB)
Process A (50KB)
Free (30KB)
Process B (40KB)
Free (20KB)
Process C (60KB)
Free (200KB)
After Compaction
OS (100KB)
Process A (50KB)
Process B (40KB)
Process C (60KB)
Free (250KB)
Compaction Benefits
  • Eliminates external fragmentation
  • Creates large contiguous free space
  • Improves memory utilization
  • Enables larger allocations
Compaction Costs
  • High CPU overhead
  • Requires relocatable programs
  • Temporary system pause
  • Complex implementation

Memory Protection and Sharing

Memory protection ensures that processes cannot access memory outside their allocated regions, while sharing mechanisms allow controlled access to common resources.

Hardware Protection Mechanisms

Base and Limit Registers

Base Register: Contains starting physical address of process

Limit Register: Contains size of process memory

Protection Check:
if (logical_address >= limit_register)
    generate_trap(SEGMENTATION_VIOLATION);
else
    physical_address = base_register + logical_address;
Base-Limit Protection
Process Memory Space
Base: 300KB
Limit: 120KB
Valid Range: 300KB - 420KB
Invalid Access
Process Memory
Invalid Access

Memory Sharing

Shared Memory Benefits

Multiple processes can access the same physical memory region, enabling efficient communication and resource sharing while reducing memory usage.

Code Sharing
  • Read-only program code
  • Shared libraries (DLLs)
  • System utilities
  • Reduces memory footprint
Data Sharing
  • Shared data structures
  • Inter-process communication
  • Requires synchronization
  • Read-write access control
Library Sharing
  • Dynamic link libraries
  • Runtime linking
  • Version management
  • Memory efficiency

Address Binding and Program Loading

Address binding determines when logical addresses are mapped to physical addresses. Different binding times offer various trade-offs between flexibility and performance.

Types of Address Binding

Compile-Time Binding

When: During compilation

Addresses: Absolute addresses generated

Flexibility: None - fixed memory location

Use Case: Embedded systems, MS-DOS .COM files

Example:
mov ax, [1000h]  ; Fixed address
jmp 2000h        ; Fixed jump target

Pros: Fast execution
Cons: No relocation
Load-Time Binding

When: During program loading

Addresses: Relocatable code adjusted

Flexibility: Can load at different locations

Use Case: Traditional operating systems

Example:
mov ax, [R+100h] ; Relocatable
jmp R+200h       ; R = base address

Pros: Relocatable
Cons: Fixed during execution
Execution-Time Binding

When: During program execution

Addresses: Dynamic translation via MMU

Flexibility: Can move during execution

Use Case: Modern virtual memory systems

Example:
mov ax, [100h]   ; Logical address
                 ; MMU translates to physical

Pros: Full flexibility
Cons: Hardware overhead

Program Loading Process

Loading Process Steps
1. Load

Copy program from storage to memory

2. Allocate

Assign memory space for program

3. Link

Resolve external references

4. Relocate

Adjust addresses for actual location

Logical vs Physical Addresses

Logical Address
  • Generated by CPU during execution
  • Also called virtual address
  • Seen by the running program
  • Independent of physical memory
  • Range: 0 to max logical space
Physical Address
  • Actual address in memory hardware
  • Also called real address
  • Hidden from programs
  • Limited by physical memory size
  • Range: 0 to max physical memory

Address Translation

Basic Address Translation:
Physical Address = Base Register + Logical Address
Address Translation Example:

Process Information:
- Base Register: 14000
- Limit Register: 3000
- Logical Address: 346

Translation Process:
1. Check bounds: 346 < 3000 ✓ (valid)
2. Calculate physical: 14000 + 346 = 14346
3. Access memory at physical address 14346

If logical address ≥ limit register:
- Generate segmentation fault
- Terminate process or handle exception

Memory Management Unit (MMU)

The MMU is a hardware component that handles address translation and memory protection, enabling efficient virtual memory systems.

MMU Functions

Address Translation
  • Converts logical to physical addresses
  • Uses translation tables
  • Hardware-accelerated process
  • Transparent to programs
Memory Protection
  • Enforces access permissions
  • Prevents unauthorized access
  • Generates protection faults
  • Supports privilege levels

MMU Operation

MMU Address Translation Process
CPU
Logical Address
MMU
Physical Address
Memory

Dynamic Loading and Linking

Dynamic loading and linking allow programs to load code and link libraries at runtime, improving memory efficiency and flexibility.

Dynamic Loading

Concept

Routines are loaded into memory only when they are called, reducing memory usage and startup time.

Advantages
  • Reduced memory usage
  • Faster program startup
  • Better memory utilization
  • Support for large programs
Disadvantages
  • Runtime loading overhead
  • Complex implementation
  • Potential loading delays
  • Dependency management

Dynamic Linking

Aspect Static Linking Dynamic Linking
Link Time Compile/build time Runtime
Library Code Included in executable Separate library files
Memory Usage Higher (duplicate libraries) Lower (shared libraries)
Executable Size Larger Smaller
Dependencies Self-contained Requires library files
Updates Requires recompilation Library updates sufficient
Flexibility Less flexible More flexible (can update modules independently)
Performance Faster startup, possible higher memory use Slower on first use, but more efficient overall
Compaction Example
Before Compaction
OS (100KB)
Process A (50KB)
Free (30KB)
Process B (40KB)
Free (20KB)
Process C (60KB)
Free (40KB)

Total Free: 90KB, Largest: 40KB

After Compaction
OS (100KB)
Process A (50KB)
Process B (40KB)
Process C (60KB)
Free (90KB)

Total Free: 90KB, Largest: 90KB

Compaction Challenges:
1. Cost: Must relocate all processes and update address references
2. Time: System may be unavailable during compaction
3. Complexity: Need to update all pointers and addresses
4. Frequency: When to perform compaction?

Solutions:
- Hardware relocation registers (base + limit)
- Virtual memory systems (eliminate need for compaction)
- Garbage collection techniques
- Non-contiguous allocation methods

Memory Protection and Sharing

Memory protection ensures that processes cannot access memory outside their allocated regions, while memory sharing allows controlled access to common resources.

Memory Protection Mechanisms

1. Base and Limit Registers
Hardware Protection Scheme
CPU with Protection Hardware
CPU Registers:
┌─────────────────┐
│ Base Register   │ → 300400
├─────────────────┤
│ Limit Register  │ → 120900
├─────────────────┤
│ Logical Address │ → 346
└─────────────────┘

Protection Check:
if (logical_address >= limit)
    trap to OS (segmentation fault)
else
    physical_address = base + logical_address
Memory Layout
Operating System
Free Space
Process (Base: 300400)
Process Memory
End (300400+120900)
Free Space
Protection Algorithm
Hardware Protection Check (performed on every memory access):

1. CPU generates logical address (LA)
2. Check: if (LA >= Limit Register)
   - Generate trap/interrupt
   - OS handles segmentation violation
   - Typically terminates process
3. If valid: Physical Address = Base Register + LA
4. Access memory at physical address

Example:
Base = 300400, Limit = 120900
Logical Address = 346

Check: 346 < 120900? ✓ Valid
Physical Address = 300400 + 346 = 300746

Invalid Example:
Logical Address = 130000
Check: 130000 < 120900? ✗ Invalid → TRAP
2. Memory Protection Bits
Protection Bit Meaning Operations Allowed Example Use
r-- Read Only Load instructions Code segment, constants
rw- Read-Write Load, store instructions Data segment, stack
r-x Read-Execute Load, jump instructions Code segment
rwx Read-Write-Execute All operations Self-modifying code
--- No Access None (trap on access) Guard pages, freed memory

Memory Sharing

Shared Memory Benefits
  • Efficiency: Reduce memory usage by sharing common code/data
  • Communication: Fast inter-process communication mechanism
  • Consistency: Single copy ensures data consistency
  • Performance: Avoid copying large data structures
Types of Memory Sharing
Code Sharing

Scenario: Multiple processes using same program

Requirements:

  • Code must be reentrant (read-only)
  • No self-modifying code
  • Position-independent or same virtual addresses
Example: Text Editor
- 3 users running same editor
- Code segment: 2MB
- Without sharing: 3 × 2MB = 6MB
- With sharing: 1 × 2MB = 2MB
- Memory saved: 4MB (67% reduction)
Data Sharing

Scenario: Processes sharing data structures

Requirements:

  • Synchronization mechanisms needed
  • Consistent virtual addresses
  • Proper access control
Example: Shared Database Buffer
- Multiple database processes
- Shared buffer pool: 100MB
- Synchronization: Semaphores/locks
- Benefits: Consistent cache, reduced I/O

Shared Memory Implementation

Shared Memory Layout
Process A Address Space
Stack A
Free Space
Heap A
Shared Memory
Data A
Shared Code
Process B Address Space
Stack B
Free Space
Heap B
Shared Memory
Data B
Shared Code
Physical Memory
Operating System
Stack A
Stack B
Shared Memory (1 copy)
Shared Code (1 copy)
Other Data

Protection Violations and Handling

Common Protection Violations:

1. Segmentation Fault (SIGSEGV):
   - Access outside allocated memory
   - Write to read-only memory
   - Execute non-executable memory
   
2. Bus Error (SIGBUS):
   - Misaligned memory access
   - Access to unmapped memory
   
3. Stack Overflow:
   - Stack grows beyond limit
   - Infinite recursion
   
OS Response to Violations:
1. Hardware generates trap/interrupt
2. OS trap handler invoked
3. Identify violating process
4. Check if violation is recoverable:
   - Recoverable: Expand stack, load page
   - Non-recoverable: Terminate process
5. Send signal to process (SIGSEGV, SIGBUS)
6. Process can handle signal or be terminated

Example Handler:
void segfault_handler(int sig) {
    printf("Segmentation fault detected!\n");
    printf("Cleaning up resources...\n");
    exit(1);
}

signal(SIGSEGV, segfault_handler);

Address Binding and Program Loading

Address binding is the process of mapping program addresses to actual memory locations. This can happen at different times during program execution.

Types of Address Binding

Compile Time

When: During compilation

Characteristics:

  • Absolute addresses generated
  • Program must load at specific location
  • Fast execution (no translation)
  • Inflexible memory placement
Example:
Source: int x = 10;
Compiled: LOAD 0x401000
         STORE 0x401004

Fixed at address 0x401000
Load Time

When: When program is loaded

Characteristics:

  • Relocatable code generated
  • Addresses adjusted at load time
  • More flexible than compile-time
  • Still fixed during execution
Example:
Relocatable: LOAD R+0
            STORE R+4

At load time: R = 0x500000
Result: LOAD 0x500000
        STORE 0x500004
Execution Time

When: During program execution

Characteristics:

  • Dynamic address translation
  • Process can move during execution
  • Requires hardware support (MMU)
  • Most flexible approach
Example:
Logical: LOAD 0x1000
        STORE 0x1004

Runtime: Base = 0x300000
Physical: LOAD 0x301000
         STORE 0x301004

Program Loading Process

From Source Code to Execution
Source Code (.c)
Compiler
Object Code (.o)
Linker
Executable
Loader
Memory
Detailed Loading Steps
Step-by-Step Loading Process
1. Compilation Phase:
   - Source code → Object code
   - Symbols marked for relocation
   - External references noted

2. Linking Phase:
   - Combine multiple object files
   - Resolve external references
   - Create symbol table
   - Generate executable file

3. Loading Phase:
   a) Allocate memory space
   b) Copy program from disk to memory
   c) Relocate addresses (if needed)
   d) Initialize program counter
   e) Transfer control to program

Example Executable File Structure:
┌─────────────────────┐
│ Header              │ ← File format info
├─────────────────────┤
│ Text Segment        │ ← Executable code
├─────────────────────┤
│ Data Segment        │ ← Initialized data
├─────────────────────┤
│ Symbol Table        │ ← Debug information
├─────────────────────┤
│ Relocation Info     │ ← Address fixup data
└─────────────────────┘

Dynamic Linking and Loading

Dynamic vs Static Linking

Static linking includes all library code in executable. Dynamic linking loads libraries at runtime.

Static Linking

Process: All libraries included at link time

Advantages:

  • Self-contained executable
  • No runtime dependencies
  • Faster program startup
  • Predictable behavior

Disadvantages:

  • Large executable files
  • Memory waste (duplicate libraries)
  • Must relink for library updates
Dynamic Linking

Process: Libraries loaded at runtime

Advantages:

  • Smaller executable files
  • Shared libraries save memory
  • Easy library updates
  • Plugin architecture support

Disadvantages:

  • Runtime dependencies
  • Slower program startup
  • Version compatibility issues

Shared Libraries Implementation

Dynamic Library Loading Process:

1. Program Startup:
   - OS loader examines executable
   - Identifies required shared libraries
   - Checks if libraries already in memory

2. Library Loading:
   - If not loaded: Load library into memory
   - If already loaded: Map to process address space
   - Update process page tables

3. Symbol Resolution:
   - Resolve function/variable addresses
   - Update program's jump tables
   - Perform relocations if necessary

Example: Linux Shared Library (.so)
Program: myapp
Library: libmath.so.1

Loading sequence:
1. execve("myapp")
2. Loader reads ELF header
3. Finds dependency: libmath.so.1
4. Searches library paths: /lib, /usr/lib, LD_LIBRARY_PATH
5. Maps library into process address space
6. Resolves symbols (sqrt, sin, cos, etc.)
7. Updates Procedure Linkage Table (PLT)
8. Transfers control to main()

Memory Layout After Loading:
┌─────────────────────┐ ← High addresses
│ Stack               │
├─────────────────────┤
│ Shared Libraries    │ ← libmath.so, libc.so
├─────────────────────┤
│ Heap                │
├─────────────────────┤
│ BSS                 │
├─────────────────────┤
│ Data                │
├─────────────────────┤
│ Text                │
└─────────────────────┘ ← Low addresses

Position Independent Code (PIC)

Position Independent Code

Code that can execute correctly regardless of its absolute address in memory. Essential for shared libraries.

Non-PIC Code (Position Dependent):
    mov eax, [0x401000]    ; Absolute address
    call 0x402000          ; Absolute function address

PIC Code (Position Independent):
    mov eax, [ebx+offset]  ; Relative to base register
    call function@PLT      ; Through procedure linkage table

PIC Implementation Techniques:

1. Relative Addressing:
   - Use PC-relative addressing modes
   - Calculate addresses relative to current instruction

2. Global Offset Table (GOT):
   - Table of addresses for global variables
   - Accessed via base register

3. Procedure Linkage Table (PLT):
   - Indirect function calls
   - Allows lazy binding of function addresses

Example PIC Function:
get_global_var:
    call get_pc           ; Get current PC
get_pc:
    pop ebx               ; EBX = current PC
    add ebx, offset_to_GOT ; EBX = GOT base
    mov eax, [ebx+var_offset] ; Load variable address
    ret

Benefits of PIC:
- Shared libraries can load at any address
- Multiple processes can share same library code
- Reduces memory usage
- Enables ASLR (Address Space Layout Randomization)

Logical vs Physical Addresses

Understanding the distinction between logical and physical addresses is crucial for memory management systems.

Address Types Comparison

Aspect Logical Address Physical Address
Definition Address generated by CPU during execution Actual address in physical memory
Also Known As Virtual address Real address, absolute address
Generated By CPU/Program Memory Management Unit (MMU)
Visibility Visible to user program Hidden from user program
Address Space Logical address space Physical address space
Range 0 to max (CPU architecture) 0 to max (physical memory size)
Modification Can be changed by user Cannot be changed by user

Address Translation Process

Logical to Physical Address Translation
CPU
Logical Address
MMU
Physical Address
Physical Memory
Translation: Physical Address = f(Logical Address)

Simple Address Translation Schemes

1. Direct Mapping (Compile-time Binding)
One-to-One Mapping
Physical Address = Logical Address
Characteristics:
- Logical and physical addresses are identical
- Used in simple systems, embedded systems
- No address translation overhead
- Limited flexibility

Example:
Logical Address:  0x1000
Physical Address: 0x1000 (same)

Memory Layout:
┌─────────────────────┐ 0xFFFF
│ Available Memory    │
├─────────────────────┤ 0x2000
│ Process Memory      │
├─────────────────────┤ 0x1000
│ Operating System    │
└─────────────────────┘ 0x0000
2. Base Register Translation
Base + Offset
Physical Address = Base Register + Logical Address
Hardware Requirements:
- Base register (relocation register)
- Adder circuit in MMU

Example:
Base Register:    0x14000
Logical Address:  0x0346
Physical Address: 0x14000 + 0x0346 = 0x14346

Translation Process:
1. CPU generates logical address (0x0346)
2. MMU adds base register value (0x14000)
3. Result is physical address (0x14346)
4. Memory access at physical address

Benefits:
- Simple hardware implementation
- Supports process relocation
- Protection through limit register
- Fast translation (single addition)

Address Space Examples

32-bit System Example
Logical Address Space:
- Size: 2^32 = 4 GB
- Range: 0x00000000 to 0xFFFFFFFF
- Per-process: Each process sees 4GB

Typical Layout:
0xFFFFFFFF ┌─────────────────┐
           │ Kernel Space    │ 1GB
0xC0000000 ├─────────────────┤
           │ User Space      │ 3GB
           │                 │
           │ Stack           │
           │ ↓               │
           │                 │
           │ ↑               │
           │ Heap            │
           │ BSS             │
           │ Data            │
           │ Text            │
0x00000000 └─────────────────┘

Physical Memory:
- Actual RAM: 512MB, 1GB, 2GB, etc.
- Managed by OS memory manager
- Shared among all processes
64-bit System Example
Logical Address Space:
- Size: 2^64 = 16 EB (exabytes)
- Range: 0x0000000000000000 to 
         0xFFFFFFFFFFFFFFFF
- Practical: Usually 48-bit (256TB)

Typical Layout:
0xFFFFFFFFFFFFFFFF ┌─────────────┐
                  │ Kernel      │
0xFFFF800000000000 ├─────────────┤
                  │ Unused      │
0x00007FFFFFFFFFFF ├─────────────┤
                  │ User Space  │
                  │             │
                  │ Stack       │
                  │ ↓           │
                  │             │
                  │ ↑           │
                  │ Heap        │
                  │ BSS         │
                  │ Data        │
                  │ Text        │
0x0000000000000000 └─────────────┘

Advantages:
- Huge address space
- No address space exhaustion
- Better security (ASLR)
- Future-proof design

Address Translation Performance

Translation Overhead Analysis
Performance Considerations:

1. Translation Frequency:
   - Every memory access requires translation
   - Instruction fetch: ~1 per instruction
   - Data access: 0-2 per instruction
   - Total: 1-3 translations per instruction

2. Hardware Translation (Base + Limit):
   - Time: 1-2 CPU cycles
   - Overhead: ~5-10% performance impact
   - Implementation: Simple adder circuit

3. Software Translation:
   - Time: 10-100 CPU cycles
   - Overhead: 50-200% performance impact
   - Implementation: OS routine call

4. Optimization Techniques:
   - Translation Lookaside Buffer (TLB)
   - Caching recent translations
   - Parallel translation and memory access
   - Specialized MMU hardware

Example Performance Impact:
Without MMU: 100 MIPS (Million Instructions Per Second)
With MMU:    90-95 MIPS (5-10% overhead)

Memory Access Pattern:
Instruction: LOAD R1, [R2+100]
1. Fetch instruction: Translate PC → Physical
2. Decode instruction
3. Calculate address: R2+100 (logical)
4. Translate data address: Logical → Physical  
5. Access memory at physical address
6. Load data into R1

Total translations: 2 (instruction + data)

Memory Management Unit (MMU)

The Memory Management Unit (MMU) is a hardware component responsible for translating logical (virtual) addresses generated by the CPU into physical addresses in main memory. It also enforces memory protection, isolation, and access control between processes.

Key MMU Functions
  • Address Translation: Converts virtual addresses to physical addresses using hardware mechanisms (e.g., base-limit registers, page tables).
  • Memory Protection: Prevents processes from accessing memory regions outside their allocation.
  • Access Control: Enforces permissions (read, write, execute) on memory regions.
  • Isolation: Ensures that processes cannot interfere with each other's memory.
  • Support for Virtual Memory: Enables features like paging and segmentation.
MMU Operation Diagram
MMU Address Translation Diagram

MMU translates virtual addresses to physical addresses and enforces protection.

Base-Limit Register Example
if (logical_address >= limit) {
    // Address out of bounds: trap to OS
    raise_exception("Segmentation Fault");
} else {
    physical_address = base + logical_address;
    // Access memory at physical_address
}
  • Base Register: Start of process memory in physical RAM
  • Limit Register: Size of process memory
  • Protection: Any access outside [base, base+limit) is trapped
MMU with Paging
Virtual Address (VA) = [Page Number | Offset]
Physical Address (PA) = [Frame Number | Offset]

Translation Steps:
1. Extract page number from VA
2. Use page number to index into page table
3. Get frame number from page table entry
4. Combine frame number with offset to form PA
5. Access memory at PA
  • Page Table: Data structure mapping virtual pages to physical frames
  • TLB (Translation Lookaside Buffer): Cache for recent address translations to speed up access
MMU Performance Considerations
  • Address translation can add overhead to every memory access
  • Hardware optimizations (e.g., TLB) minimize performance impact
  • Page faults (when a page is not in memory) cause significant delays
Summary Table: MMU Features
Feature Description
Address Translation Virtual → Physical address mapping
Protection Prevents illegal memory access
Isolation Separates process address spaces
Access Control Enforces read/write/execute permissions
Support for Virtual Memory Enables paging, segmentation, and swapping

Dynamic Loading

Dynamic loading is a technique where a program loads routines or modules into memory only when they are needed, rather than loading everything at program startup. This approach helps reduce the initial memory footprint and can improve overall system efficiency.

How Dynamic Loading Works
  • When a program starts, only the main routine is loaded into memory.
  • Other routines (e.g., error handlers, infrequently used features) are kept on disk.
  • When the program needs a routine, it loads it from disk into memory at runtime.
  • This is typically managed by the operating system or a dynamic loader within the program.
Benefits:
  • Reduces memory usage by loading only what is needed.
  • Allows for larger programs to run on systems with limited memory.
  • Enables updates or patches to routines without recompiling the entire program.
Key Concept

Dynamic loading is especially useful for large applications and operating systems, where not all features are used all the time. It is a foundation for advanced techniques like dynamic linking and shared libraries.

Example: Dynamic Loading in C

// Example: Using dlopen() and dlsym() for dynamic loading (POSIX)
#include <dlfcn.h>
void *handle = dlopen("libmath.so", RTLD_LAZY);
if (handle) {
    double (*cosine)(double) = dlsym(handle, "cos");
    if (cosine) {
        printf("cos(2.0) = %f\n", cosine(2.0));
    }
    dlclose(handle);
}
This code loads a math library at runtime and calls the cos function only if needed.
Dynamic Loading vs. Static Loading
Aspect Static Loading Dynamic Loading
When Loaded At program start At runtime, when needed
Memory Usage Higher (all routines loaded) Lower (only needed routines loaded)
Flexibility Less flexible More flexible (can update modules independently)
Performance Faster startup, possible higher memory use Slower on first use, but more efficient overall

Session Summary

Key Takeaways:
  • Memory Hierarchy: Understanding the speed-capacity trade-offs from registers to storage
  • Address Spaces: Distinction between logical and physical addresses and their management
  • Memory Allocation: Fixed vs dynamic partitioning, allocation algorithms, and fragmentation
  • Protection Mechanisms: Base-limit registers, protection bits, and access control
  • Address Binding: Compile-time, load-time, and execution-time binding strategies
  • MMU Operations: Hardware-based address translation and protection enforcement
  • Dynamic Loading: On-demand loading for improved memory efficiency
Study Tips:
  • Practice address translation calculations
  • Understand fragmentation types and solutions
  • Work through memory allocation examples
  • Analyze performance trade-offs
  • Review MMU hardware concepts
Critical Concepts:
  • Memory Hierarchy: Cache → RAM → Storage performance gaps
  • Address Translation: Logical to physical mapping mechanisms
  • Fragmentation: Internal vs external fragmentation causes and solutions
  • Protection: Hardware-enforced memory access control
  • Sharing: Code and data sharing between processes
Practical Applications:
  • Operating system memory managers
  • Virtual memory systems
  • Embedded system memory optimization
  • Database buffer management
  • Application memory profiling
Next Session:

Session 4.2: Paging and Virtual Memory
Page-based memory management, virtual memory concepts, and demand paging systems