Fundamentals 12 min read

OS Memory Management Explained: Allocation Strategies & Page Replacement in Go

This article delves into operating system memory management, covering continuous and fragmented allocation strategies such as First‑Fit, Next‑Fit, Best‑Fit, and Worst‑Fit, explains swapping and overlay techniques, analyzes page replacement algorithms like Optimal, FIFO, and LRU, and offers practical Go implementations and optimization tips.

Code Wrench
Code Wrench
Code Wrench
OS Memory Management Explained: Allocation Strategies & Page Replacement in Go

Introduction

In the rapidly evolving field of computer technology, the operating system (OS) is the core of resource management, ensuring efficient system operation. Many beginners lack solid foundational knowledge, which hampers their ability to handle complex problems. This article explores OS memory management mechanisms, detailing memory allocation and page replacement algorithms, and provides concrete Go implementations.

Memory Allocation Strategies

Memory allocation is the key mechanism by which an OS manages physical memory, aiming to use limited memory resources efficiently so that processes can run smoothly. Allocation strategies fall into two major categories: continuous allocation and fragmented (non‑contiguous) allocation.

Continuous Allocation Strategies

Continuous allocation was widely used in early operating systems. Although simple to implement, it easily leads to memory fragmentation, degrading system performance. Classic continuous allocation algorithms include:

First‑Fit : Scans memory from the low address upward and allocates the first free block large enough for the process. Simple and fast, but can cause front‑end fragmentation.

func firstFit(memoryBlocks []int, processSize int) int {
    for i := range memoryBlocks {
        if memoryBlocks[i] >= processSize {
            memoryBlocks[i] -= processSize
            return i // return allocated block index
        }
    }
    return -1 // allocation failed
}

Next‑Fit : Continues scanning from the position where the last allocation ended, reducing front‑end fragmentation.

func nextFit(memoryBlocks []int, processSize int, lastAllocatedIndex int) int {
    n := len(memoryBlocks)
    for i := 0; i < n; i++ {
        index := (lastAllocatedIndex + i) % n
        if memoryBlocks[index] >= processSize {
            memoryBlocks[index] -= processSize
            return index // return allocated block index
        }
    }
    return -1 // allocation failed
}

Best‑Fit : Searches all free blocks and selects the smallest block that can accommodate the process, minimizing leftover space but potentially creating many small fragments.

func bestFit(memoryBlocks []int, processSize int) int {
    bestIndex := -1
    minDiff := int(^uint(0) >> 1) // max int
    for i := range memoryBlocks {
        if memoryBlocks[i] >= processSize && (memoryBlocks[i]-processSize) < minDiff {
            bestIndex = i
            minDiff = memoryBlocks[i] - processSize
        }
    }
    if bestIndex != -1 {
        memoryBlocks[bestIndex] -= processSize
    }
    return bestIndex // -1 indicates failure
}

Worst‑Fit : Chooses the largest free block for allocation, preserving larger blocks for future use, but can worsen fragmentation.

func worstFit(memoryBlocks []int, processSize int) int {
    worstIndex := -1
    maxDiff := -1
    for i := range memoryBlocks {
        if memoryBlocks[i] >= processSize && (memoryBlocks[i]-processSize) > maxDiff {
            worstIndex = i
            maxDiff = memoryBlocks[i] - processSize
        }
    }
    if worstIndex != -1 {
        memoryBlocks[worstIndex] -= processSize
    }
    return worstIndex // -1 indicates failure
}

Swapping and Overlay Techniques

When memory resources are insufficient, the OS employs swapping to move temporarily unused processes or data out of RAM, freeing space for active processes. Overlay loads and replaces program segments dynamically based on current needs, further conserving memory.

Whole‑process swapping moves an entire process in or out of memory.

Paging (or segment) swapping moves individual pages or segments, offering finer granularity and flexibility.

Page Replacement Algorithms

When physical memory is full, the OS must decide which pages to evict. Key algorithms include:

Optimal Replacement : Evicts the page that will not be used for the longest future interval. Theoretically yields the lowest miss rate but is impractical because future references are unknown.

func optimalReplace(pages []int, frameCount int, futureReferences []int) int {
    farthestIndex := -1
    replacePageIndex := -1
    for i := 0; i < frameCount; i++ {
        found := false
        for j := 0; j < len(futureReferences); j++ {
            if pages[i] == futureReferences[j] {
                if j > farthestIndex {
                    farthestIndex = j
                    replacePageIndex = i
                }
                found = true
                break
            }
        }
        if !found {
            return i
        }
    }
    return replacePageIndex
}

FIFO (First‑In‑First‑Out) : Replaces the oldest page in memory. Simple to implement but may suffer high miss rates.

func fifoReplace(pages []int, frameQueue []int) int {
    replaceIndex := frameQueue[0]
    frameQueue = append(frameQueue[1:], replaceIndex)
    return replaceIndex
}

LRU (Least Recently Used) : Replaces the page that has not been used for the longest time, based on recent access history. More accurate than FIFO but more complex to implement.

func lruReplace(pages []int, recentUse []int) int {
    lruIndex := 0
    minUseTime := recentUse[0]
    for i := 1; i < len(recentUse); i++ {
        if recentUse[i] < minUseTime {
            lruIndex = i
            minUseTime = recentUse[i]
        }
    }
    return lruIndex
}

Memory Optimization Strategies

Beyond the OS’s default mechanisms, developers can adopt several techniques to improve memory efficiency:

Reduce Allocation/Deallocation Frequency : Frequent allocations cause fragmentation. Use object pools to recycle memory.

Optimize Data Structures : Choose structures that minimize overhead, e.g., arrays instead of linked lists for small items, shared or compressed storage for large collections.

Memory‑Mapped Files : Map large files directly into address space to avoid loading entire files into RAM.

Lazy Loading : Load resources only when needed, which is especially effective for large‑scale data processing.

Development Advice for Beginners

Understanding OS memory management is crucial for writing efficient code and solving complex problems. Beginners should:

Deepen theoretical knowledge of operating systems, data structures, and algorithms.

Practice extensively and reflect on failures rather than seeking quick fixes.

Continuously consider performance and resource usage, learning from high‑quality code and literature.

Engage with more experienced developers to exchange techniques and insights.

Conclusion

OS memory management is vital for overall system performance. By analyzing allocation strategies and page replacement algorithms, and providing concrete Go implementations, this article equips programmers with the knowledge to manage memory resources effectively and adopt optimization practices for building faster, more stable software.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

osMemoryallocationpage-replacement
Code Wrench
Written by

Code Wrench

Focuses on code debugging, performance optimization, and real-world engineering, sharing efficient development tips and pitfall guides. We break down technical challenges in a down-to-earth style, helping you craft handy tools so every line of code becomes a problem‑solving weapon. 🔧💻

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.