Module 3 · Unit 9 · Discussion 9
Diagnosing a Page-Fault Storm
Virtual memory gives a program the illusion that it has more memory than the machine physically has. The illusion is maintained by demand paging: pages are loaded only when they are referenced, and pages that are no longer needed are evicted to make room. When the working set of the running processes exceeds physical memory, the system spends most of its time servicing page faults rather than doing useful work — a condition called thrashing. This discussion asks you to diagnose a real page-fault workload, decide whether it is thrashing, and propose a tuning that improves it.
01 Overview
| Course | COMP 3150 / CMIS 3150 — Operating Systems |
|---|---|
| Unit | Unit 9 — Virtual Memory |
| Weight | Part of the 5% participation grade (each discussion is worth approximately 0.4% of the final grade) |
| Opens | Monday of Week 9 |
| Initial post due | Thursday of Week 9, 23:59 |
| Peer replies due | Sunday of Week 9, 23:59 |
| Format | One initial post (500–700 words, including a table of measured fault rates) and at least two substantive peer replies (150–250 words each) |
| CLOs assessed | CLO4, CLO6, CLO8 |
02 Learning outcomes addressed
By participating in this discussion you will
- Explain the paging model and translate a virtual address to a physical address through a page table (U9.1, U9.2).
- Describe the role of the TLB and its effect on translation cost (U9.3).
- Explain demand paging and the difference between a minor and a major page fault (U9.4, U9.5).
- Compare page-replacement algorithms — FIFO, LRU, Clock, Optimal — and explain their trade-offs (U9.6).
- Diagnose thrashing and propose a tuning that improves it (U9.7).
This discussion assesses CLO4 (explain virtual-memory management), CLO6 (apply Linux systems programming and tools), and CLO8 (design and implement OS-related components).
03 Discussion prompt
The scenario
A server is running a data-processing service. Under moderate load the service performs well, but under heavy load its throughput collapses: latency increases sharply, CPU utilisation rises (mostly in system time, not user time), and the disk's I/O queue saturates. The service's operators have noticed that the problem gets worse when more worker processes are added, which is counter-intuitive — adding workers should increase throughput, not decrease it.
You have been asked to diagnose the problem and to propose a tuning that improves the service's throughput at high load.
Your task
-
Choose a workload to diagnose.
You have two options:
- Construct the workload. Write or use a workload that exercises a large memory footprint — for example, a program that allocates and traverses a large array, or several processes that each allocate more than the machine's physical memory. Run one, two, four, and eight instances of it in parallel and observe the behaviour.
-
Use an existing workload.
Choose a real application (for example, a
compiler building a large project, a
database running a large query, or a
machine-learning training job) and run it
under different memory pressures (for
example, by using
ulimit -vor a cgroup memory limit).
-
Measure the page-fault behaviour.
For each run, record:
-
The number of minor and
major page faults. Use
/usr/bin/time -v(lines "Minor (reclaiming a frame) page faults" and "Major (requiring I/O) page faults"), or read/proc/<pid>/stat(fields 10 and 12). - The throughput of the workload (for example, transactions per second, or jobs completed per minute).
-
The CPU utilisation:
user time versus system time. Use
top,pidstat, or/proc/<pid>/stat(fields 14 and 15). -
The disk I/O of the
workload and the system-wide swap
activity. Use
iostat,vmstat(columnssiandso), or/proc/vmstat(fieldspswpinandpswpout).
-
The number of minor and
major page faults. Use
- Diagnose the problem. Present your results in a table (one row per run, one column per metric). State whether the workload is thrashing, and justify your answer with the data. The signature of thrashing is: a high rate of major faults, high system time relative to user time, high disk I/O (often to swap), and decreasing throughput as the number of concurrent workloads increases. State whether all of these signatures are present in your data. If they are not, what is the actual cause of the throughput drop?
-
Propose a tuning.
On the basis of your diagnosis, propose one
or more tunings that would improve the
workload's throughput. Examples:
- Reduce the number of concurrent processes, or set a cgroup memory limit that is smaller than the sum of the processes' working sets.
- Reduce the working set of each process (for example, by processing the data in smaller batches).
- Increase the machine's memory, or enable huge pages so that more of the working set fits in the TLB.
-
Tune the kernel's swappiness
(
vm.swappiness) or dirty page writeback parameters (vm.dirty_ratioandvm.dirty_background_ratio).
-
Explain the underlying mechanism.
Connect your diagnosis and your tuning to the
concepts of the unit:
- Why does the throughput drop when the working set exceeds physical memory?
- Why does the throughput sometimes drop further as more concurrent processes are added, rather than staying at the same level?
- What role does the page-replacement algorithm play in the transition from "performing well" to "thrashing"?
- What is the relationship between the working-set size and the number of frames the kernel allocates to each process?
Your post should be 500–700 words. Include the measurement table. State the workload, the parameters, the hardware, and the kernel version so that the experiment can be reproduced.
04 Suggested experiments and tools
4.1 A synthetic workload
Write a program that allocates a large array and traverses it. Vary the size of the array: a size that fits comfortably in physical memory, a size that is close to the limit, and a size that exceeds physical memory. Run the program in a loop and observe the fault rate.
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char **argv) {
size_t size = (argc > 1 ? atol(argv[1]) : 1) * 1024ULL * 1024ULL * 1024ULL;
char *buf = malloc(size);
if (!buf) { perror("malloc"); return 1; }
for (size_t i = 0; i < size; i += 4096) {
buf[i] = (char)i; /* touch one byte per page */
}
printf("touched %zu bytes\n", size);
free(buf);
return 0;
}
Each buf[i] touches a distinct page
(because of the 4096 stride). The write causes a
page fault the first time each page is touched. Run
the program with sizes of 1 GB, 4 GB, and 8 GB on a
machine with, say, 4 GB of RAM, and compare the
fault rates.
4.2 A multi-process experiment
Run N copies of the program from § 4.1 in parallel, for N = 1, 2, 4, 8. Record the total throughput (bytes touched per second, across all processes) and the total fault rate. On a machine with limited memory, the throughput will drop as N grows beyond a threshold — that is thrashing.
4.3 Tools
-
/usr/bin/time -v ./program— reports the elapsed time, the CPU time (user and system), the maximum resident set size, and the minor and major page faults. This is the fastest way to get a snapshot of the workload's memory behaviour. -
/proc/<pid>/stat— fields 10 (minor faults), 12 (major faults), 14 (user time in clock ticks), 15 (system time). Poll it periodically to get a time series. -
vmstat 1— reports the system-wide swap-in (si) and swap-out (so) rates, the number of runnable processes (r), and the CPU time breakdown (us,sy,wa,id). Thewacolumn (I/O wait) will be high during thrashing. -
perf stat -e page-faults,minor-faults,major-faults ./program— counts faults using hardware performance counters; the counts may differ slightly from/procbecause they are measured at a different point. -
/proc/vmstat— fieldspgfaultandpgmajfault(system-wide), andpswpinandpswpout(system-wide swap).
4.4 Notes on interpretation
- Minor faults are not necessarily a problem. Every page of every file that a program reads causes a minor fault the first time it is touched, but the page is already in memory (in the page cache), so the fault is cheap.
- Major faults are expensive: they require disk I/O. A high rate of major faults is a strong indicator of thrashing.
-
The
wacolumn invmstatis the fraction of CPU time spent waiting for I/O. It rises during thrashing because every faulting process is blocked on the swap device. -
vm.swappinesscontrols how aggressively the kernel reclaims anonymous pages (as opposed to file-backed pages). A high value (the default, 60) means the kernel is willing to swap anonymous memory; a low value (10 or less) means it prefers to keep anonymous memory resident and reclaim file-backed pages instead. On a system with a large working set and little swap, lowering swappiness can help; on a system with plenty of swap, the default is usually fine.
05 Grading rubric
The discussion is marked out of 100 points. The criteria and their weights are given below.
| Criterion | Weight |
|---|---|
| Post quality (measurement, diagnosis, tuning, mechanism) | 40% |
| Peer response quality | 30% |
| Engagement and timeliness | 20% |
| Netiquette and clarity | 10% |
5.1 Post quality (40 points)
| Level | Descriptor |
|---|---|
| Exemplary (90–100%) | A clear workload and a reproducible experiment. The fault metrics, throughput, CPU utilisation, and I/O are measured and reported. The diagnosis identifies thrashing correctly, with the data supporting each signature. The tuning is applied and the improvement is measured. The mechanism is explained in terms of the working set, the replacement algorithm, and the frame allocation. Sources are cited. |
| Proficient (80–89%) | A clear workload. The fault metrics and throughput are measured. The diagnosis is correct, but the supporting evidence is incomplete (for example, I/O is not reported, or system time is not distinguished from user time). The tuning is proposed but not applied. The mechanism is explained briefly. |
| Developing (70–79%) | A workload is described but the experiment is incomplete (only the fault rate is measured, or the throughput is not). The diagnosis is present but not supported by the data. The tuning is vague. |
| Beginning (60–69%) | The experiment is not run, or the results are not reported. The post is a theoretical description of thrashing without measurement. |
| Not demonstrated (<60%) | The post is missing, off-topic, or a restatement of the prompt without any measurement. |
5.2 Peer response quality (30 points)
The descriptors are the same as for Discussion 3. An exemplary reply might:
- Suggest a different tuning that the classmate did not consider and predict how it would compare.
- Point out a metric the classmate should have measured (for example, the working-set size, or the TLB miss rate).
- Compare the classmate's results with their own and explain the difference in terms of hardware or workload.
5.3 Engagement and timeliness (20 points)
The descriptors are the same as for Discussion 1.
5.4 Netiquette and clarity (10 points)
The descriptors are the same as for Discussion 1.
06 Resources
- Silberschatz, A., Galvin, P. B., & Gagne, G. Operating System Concepts, 10th ed., Chapter 10 (Virtual Memory).
- Arpaci-Dusseau, R. H., & Arpaci-Dusseau, A. C. Operating Systems: Three Easy Pieces, Chapters 18–23 (Paging, TLBs, Swapping, Policy).
- Tanenbaum, A. S., & Bos, H. Modern Operating Systems, 4th ed., Chapter 3 (Memory Management, Section on Virtual Memory).
- Denning, P. J. The Working Set Model for Program Behavior. Communications of the ACM, 1968.
- Belady, L. A., Nelson, R. A., & Shedler, G. S. An Anomaly in Space-Time Characteristics of Certain Programs Running in a Paging Machine. Communications of the ACM, 1969.
- Gorman, M. Understanding the Linux Virtual Memory Manager. Prentice Hall, 2004. (Available online.)
- Linux kernel documentation:
Documentation/admin-guide/mm/,Documentation/admin-guide/sysctl/vm.rst. - Linux man-pages:
man 5 proc(/proc/<pid>/stat,/proc/<pid>/smaps,/proc/vmstat),man 1 vmstat,man 1 pidstat,man 1 perf-stat. - Drepper, U. What Every Programmer Should Know About Memory. Red Hat, 2007.