4.2.23 · D2Operating Systems

Visual walkthrough — Memory allocation — contiguous (first-fit, best-fit, worst-fit)

1,988 words9 min readBack to topic

We use one running scenario (the parent's Worked Example 1):

  • Holes in address order: (all KB).
  • Requests in arrival order: (KB).

Step 1 — Draw the shelf and name every piece

WHAT. RAM is one long horizontal strip. The dark bars are memory already used by other programs; the light bars between them are holes — unbroken stretches of free space. We label each hole with a letter and its size in KB.

WHY. Every algorithm we study does exactly one thing: it looks at this list of holes and picks one. So the only state that matters is "which holes exist, in what order, at what size." Before we can pick, we must be able to read the shelf.

PICTURE. Look at the strip below. Reading left to right (this direction is address order — low address on the left, high on the right) the free holes are . Their sizes are printed inside them. "Address order" is just the physical left-to-right order on the shelf — remember it, because first-fit scans in exactly this order.

Figure — Memory allocation — contiguous (first-fit, best-fit, worst-fit)

Step 2 — One placement: cutting a chunk and leaving a leftover

WHAT. Take request , choose a hole of size with , and place the program at the left end of that hole. The hole splits into two parts: the program (size ) and a new smaller hole (size ).

WHY. This is the atomic move every rule performs; the rules differ only in which they choose. Understand this one cut and you understand all three algorithms — they are just three answers to "which ?".

PICTURE. In the figure, the teal hole of size is sliced by the orange knife at position from its left edge. Left of the knife becomes used; right of the knife (the plum sliver, width ) becomes a new hole.

  • If : the knife lands exactly on the right edge — the hole vanishes completely.
  • If : a real sliver remains, sitting at address (hole's base ).
  • If : illegal — the knife would cut past the hole's right edge. This hole is not a candidate at all.
Figure — Memory allocation — contiguous (first-fit, best-fit, worst-fit)

Step 3 — First-fit runs: stop at the first hole that fits

WHAT. For each request, scan holes in address order () and stop at the very first one with size . Cut there.

WHY. Because we stop early, first-fit is the fastest rule: on average it touches only the first few holes. First-fit still tests each hole it visits (is ?), but it does not compare candidates against each other — the moment one passes the test, we commit. That early stop is the source of its speed.

PICTURE. The green check marks where the scan stops; grey crosses are holes it skipped past (too small) or never reached. Watch : it steps over (cross, ), lands on (check), and cuts — leaving .

Full run:

  • : ✗, ✓ → leftover .
  • : all too small, ✓ → leftover .
  • : ✗, ✓ → leftover .
  • : holes now none . FAILS.
Figure — Memory allocation — contiguous (first-fit, best-fit, worst-fit)

Step 4 — Best-fit runs: pick the tightest hole

WHAT. For each request, scan all holes, collect every candidate with size , and pick the smallest such candidate — the tightest fit.

WHY. A tight fit shaves off the smallest possible leftover this step, so intuitively it "wastes least right now." Price: we must scan the entire free list to be sure we found the smallest — slower than first-fit.

PICTURE. For the candidates () are ; the shortest of them, , glows plum (chosen), leaving only . Compare this to first-fit, which grabbed the big and wasted .

Full run:

  • : candidates → smallest → leftover .
  • : candidates → smallest → leftover .
  • : candidates (note , ) → smallest → leftover .
  • : candidate → leftover . All four succeed.
Figure — Memory allocation — contiguous (first-fit, best-fit, worst-fit)

Step 5 — Worst-fit runs: pick the widest hole

WHAT. For each request, scan all holes and pick the largest one (regardless of how much bigger it is than ).

WHY. The hope: cutting out of the biggest hole leaves the biggest possible leftover, which stays "reusable." The danger, which the picture reveals, is that you eat your big holes first — so a big future request has nothing left.

PICTURE. For every hole is a candidate (all could be widest-compared); the tallest bar is chosen and shrinks to . Notice getting nibbled twice — by the end there is no large hole for .

Full run:

  • : largest → leftover .
  • : largest → leftover .
  • : largest now → leftover .
  • : holes — largest is . FAILS.
Figure — Memory allocation — contiguous (first-fit, best-fit, worst-fit)

Step 6 — The degenerate cases (never leave the reader stranded)

WHAT. The corners the running example didn't hit. Each is a legal input the algorithm must handle.

WHY. A rule you only understand on "nice" inputs will surprise you on real workloads. Here are the four edges.

PICTURE. Four mini-shelves, labelled ① ② ③ ④ top to bottom, matching the four numbered cases below:

  1. ① Exact fit (): leftover . The hole disappears entirely — no sliver, no fragmentation from this step. Best possible outcome.
  2. ② No hole fits ( for every ): the request fails even if the total free space . Two 30 KB holes cannot host a 50 KB program — contiguity forbids splitting. (This is external fragmentation biting.)
  3. ③ Zero-size request (): trivially satisfiable by any hole; changes nothing — a well-behaved allocator returns immediately.
  4. ④ Ties (two holes equally good): best-fit and worst-fit break ties by address order (lowest first), matching first-fit's scan direction — a convention, but a fixed one, so results are reproducible.
Figure — Memory allocation — contiguous (first-fit, best-fit, worst-fit)

The one-picture summary

Below, all three rules face the same request on the same starting shelf. A legend in the corner maps each arrow's color to its algorithm: orange → first-fit (grabs , first that fits), plum → best-fit (grabs , tightest), teal → worst-fit (grabs , widest). Each arrow is also labelled in words next to its target, so the mapping never depends on color alone — the entire chapter in one image.

Figure — Memory allocation — contiguous (first-fit, best-fit, worst-fit)
Recall Feynman: the whole walkthrough in plain words

Picture a long shelf with a few empty gaps of different widths. A new book needs a gap wide enough to fit in one piece — it can't be sawn in half. First-fit: walk from the left, drop the book in the first gap it fits — quick, but you might jam a small book into a huge gap and waste it. Best-fit: check every gap and use the snuggest one — barely any space wasted this time, but you leave behind lots of gaps just a hair too small for anything. Worst-fit: always use the widest gap so the leftover stays roomy — but you chew through your big gaps fast, and later a fat book has nowhere to go. On our shelf best-fit happened to save the last big book because it left the widest gap alone until the end; first-fit and worst-fit had already eaten it. The trick is: which gap you pick reshapes all the gaps that remain, and that decides who gets in later. No rule always wins — it depends on who shows up next.


Active Recall

Best-fit's choice for among ?
(smallest candidate ), leftover .
Why does first-fit fail in the example?
It burned into and early; remaining holes max out at .
What is the leftover formula and its exact-fit case?
; when leftover is and the hole vanishes.
Can a request with fail when two KB holes are free?
Yes — contiguity forbids splitting; no single hole reaches .
Which rule leaves the biggest hole untouched longest, and why did that matter here?
Best-fit — it kept free for the large .

Connections

  • Parent topic (Hinglish)
  • Fragmentation — the slivers left by these cuts are external fragmentation.
  • Compaction — slides allocated blocks together to merge scattered leftovers.
  • Free List Management — how the OS stores and scans the hole list you saw here.
  • Paging — removes the contiguity requirement that made the corner case fail.
  • Segmentation — variable-size contiguous chunks, same placement rules per segment.
  • Buddy System — a different splitting scheme that bounds leftover sizes.