Thrashing
AdvancedThrashing occurs when a process spends more time paging than executing, caused by insufficient physical frames to hold the active working set, collapsing CPU utilisation.
Overview
When the OS keeps too many processes active simultaneously and physical memory is insufficient to hold all their working sets, processes constantly page fault. Each fault causes a process to block (waiting for disk I/O), which frees the CPU — but the scheduler loads another process whose pages also fault immediately. The CPU becomes fully occupied handling page faults rather than executing user instructions; CPU utilisation collapses despite 100% CPU activity. This is thrashing. The working set model (Denning, 1968) defines the working set W(t, Δ) as the set of pages referenced in the last Δ time units. If the sum of all processes' working set sizes exceeds physical RAM, thrashing is inevitable. Solutions: reduce the degree of multiprogramming (swap out entire processes), use the working set model to decide when to admit new processes, or use the page fault frequency (PFF) algorithm — if a process's fault rate exceeds an upper threshold, give it more frames; if below a lower threshold, take frames away.
Thrashing Diagnosis and the Working Set Model
The thrashing symptom is counterintuitive: adding more processes to an already-thrashing system makes it worse, not better. CPU utilisation peaks, then rapidly drops as the degree of multiprogramming increases beyond the point where working sets fit in RAM. The working set window Δ controls sensitivity: too small misses long-term patterns; too large includes irrelevant pages.
// Working Set Model — conceptual simulation
// Working set W(t, Δ) = distinct pages referenced in last Δ time units
int[] accessHistory = {1,2,3,1,4,2,5,3,1,2,3,4,1,2}; // page reference string
int delta = 5; // working set window size
for (int t = delta; t <= accessHistory.length; t++) {
// Working set at time t = unique pages in [t-delta, t)
Set<Integer> workingSet = new HashSet<>();
for (int i = t - delta; i < t; i++) {
workingSet.add(accessHistory[i]);
}
System.out.printf("t=%2d Working set size: %d pages: %s%n",
t, workingSet.size(), workingSet);
}
// Total working set demand = sum of all process working set sizes
// If total demand > physical frames → THRASHING inevitable
// OS response: suspend (swap out) a process to reduce demand
// Detecting thrashing in production (Java metrics)
OperatingSystemMXBean osBean =
(OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
double cpuLoad = osBean.getProcessCpuLoad();
// If cpuLoad ≈ 1.0 AND throughput is near zero → likely thrashing
System.out.printf("Process CPU load: %.1f%%%n", cpuLoad * 100);Page Fault Frequency Algorithm and Mitigation
The Page Fault Frequency (PFF) algorithm controls thrashing dynamically: measure each process's page fault rate. If the rate exceeds an upper threshold, allocate more frames. If it drops below a lower threshold, reclaim frames. If no free frames exist when a process needs more, suspend (swap out) a process. In Java applications, thrashing manifests as JVM GC consuming most CPU time while the application makes no progress — sometimes called "GC thrashing" when heap is too small relative to live object count.
// Page Fault Frequency (PFF) thresholds
double upperThreshold = 0.20; // more than 20 faults/sec → need more frames
double lowerThreshold = 0.05; // fewer than 5 faults/sec → can give frames back
// Simulating PFF-based frame allocation
int[] framesAllocated = {3, 3, 3}; // 3 processes, 3 frames each
double[] faultRates = {0.30, 0.10, 0.03}; // measured fault rates
for (int i = 0; i < faultRates.length; i++) {
if (faultRates[i] > upperThreshold) {
framesAllocated[i]++;
System.out.printf("Process %d: high fault rate (%.2f) → allocate frame → now %d%n",
i, faultRates[i], framesAllocated[i]);
} else if (faultRates[i] < lowerThreshold) {
framesAllocated[i]--;
System.out.printf("Process %d: low fault rate (%.2f) → reclaim frame → now %d%n",
i, faultRates[i], framesAllocated[i]);
}
}
// Java GC thrashing mitigation:
// If JVM spends >98% time in GC → OutOfMemoryError: GC overhead limit exceeded
// Fix: increase -Xmx, reduce object creation rate, fix memory leaks
// Monitor: JConsole, VisualVM, or: -verbose:gc -XX:+PrintGCDetailsKey Points to Remember
- 1Thrashing: processes spend more time swapping pages than executing — CPU utilisation collapses.
- 2Caused by sum of all working sets exceeding available physical frames.
- 3Working set model: keep all pages referenced in the last Δ time units in memory.
- 4PFF algorithm: give more frames when fault rate is high, reclaim when low.
- 5Solution: reduce degree of multiprogramming — suspend a process to free frames for remaining ones.
- 6Java equivalent: GC thrashing when heap is too small — JVM spends >98% in GC, triggers OOM.
Interview Questions
Sign in to ask AriaWhat is thrashing and what causes it?
How does the working set model prevent thrashing?
What is the Page Fault Frequency algorithm and how does it respond to thrashing?
Describe a scenario where a Java application experiences GC thrashing and how you would fix it.
Ask Aria about Thrashing
Your personal AI tutor — ask anything about this concept
Revision Status
Personal Notes
Sign in to save personal notes for this topic.
Discussion
Sign in to join the discussion.