Skip to content

26/32 · 5 min

When the machine stops doing work

A system gets slower under load, which is expected. Then it falls off a cliff: CPU usage drops to almost nothing, the disk is constantly busy, and nothing progresses. That is thrashing.

What is happening

Each process needs more pages than it has frames. It faults, evicts a page another process needs, that process faults and evicts one back. Every fault causes another fault.

code
CPU usage
   |      ______
   |     /      \
   |    /        \
   |   /          \____________   <- thrashing
   +--------------------------------
       degree of multiprogramming

The shape is the important part. Adding processes improves utilisation up to a point, then collapses it. And the collapse is self reinforcing: a scheduler seeing low CPU usage concludes the machine is idle and admits more processes, making it worse.

The working set

The set of pages a process has used in the recent window. It reflects locality: a program in one phase touches a fairly stable group of pages, then moves on.

If every process has enough frames for its working set, faults are rare. If the sum of all working sets exceeds physical memory, thrashing is guaranteed no matter which replacement algorithm is used.

code
sum of working sets <= frames available   -> fine
sum of working sets >  frames available   -> thrashing

The policy that follows: if the sum exceeds what is available, suspend a process entirely and swap it out. Fewer processes running well beats all of them running badly, and this is one of the few cases where doing less work produces more throughput.

Page fault frequency

The practical version, which does not require tracking sets. Watch each process's fault rate: above an upper threshold, give it more frames; below a lower one, take some away. If nothing can be given, suspend something.

Recognising it

SymptomReading
CPU low, disk high, nothing finishingthrashing
CPU high, disk lowgenuinely busy, fine
Memory full but little pagingfine, the cache uses spare memory

That last row matters in practice. Linux reports almost all memory as used because it fills the remainder with file cache, and people conclude they are out of memory. The number to watch is paging activity, not free memory.

On a modern machine with SSDs and an out of memory killer, classic thrashing is rarer, and the underlying rule is unchanged: if the active data does not fit, adding work reduces throughput.