As a program runs, it commonly uses only a small percentage of its pages at any given time. This is called its working set. Suppose, for example, that the program shown in Fig. 12.2.1 from only two pages and runs code out of only one page, except for an occasional reference to a section in the other pages. We would say this program had a working set of 3 pages.
If real memory is big enough to hold the working set, then the program will execute smoothly. However, if real memory is too small, then a condition known as thrashing occurs where the program frequently brings in pages from disk, only to use them a little while and throw them out. This is a terrible situation since disk accesses are often 20,000 to 100,000 times slower than main memory accesses!
For example, suppose that only 2 frames of real memory were available, but the working set is 3 pages. Then the program would frequently reference data and instructions out of 3 pages. But at any given point, only two pages would be in memory, since that is all it can hold. When the third page is referenced, it has to be copied in from the swap area and the program can proceed. But then the page that was in the selected victim frame is now gone. Since that page will be referenced again soon, the operating system will have to bring in that page again. It is even worse if the memory is being modified, because the old dirty page must be write back to disk, making the time penalty even worse.
In real operating systems, thrashing can be induced artificially by having a program declare a huge array and randomly access parts of it repeatedly. Real programs can thrash if they are only allotted a few frames in a multiprogramming system. This not only slows down the individual program that is thrashing, but puts a huge burden on the I/O system, thereby slowing everybody down. The end result is that the system slows to the barest crawl. This author used to work on a small VAX 8260 at a large university and when it got very busy, and many users were logged in simultaneously, the slowdown was ridiculous. You could press a key and not see any reaction on your screen for 30 seconds. Hitting return to submit even the simplest command was a kamikaze act since you knew it wouldn't respond for hours! This kind of intolerable situation is the dark side of virtual memory and multiprogramming systems.