We've all experienced it. We're happily using our computer one moment, the next moment everything on the screen stops moving. You shake the mouse and jab its buttons. You run your finger along the keyboard like a pianist playing a glissando. But your program refuses to respond.
But freezing is just the symptom. There are many causes for what’s happened all of which can be grouped into one of two types: one is crashing, the other hanging. In this article, I’m going to explain what happens inside your computer when it freezes. Also I’ll offer you tips on how you might fix potential problems causing the freezing.
When reading this article, you’ll need a basic understanding of what a computer program is. Luckily, I’ve provided all the information you need in the following section. If you’re one of those smarty-pants who already knows all about programs, you can skip over it.
When things are chugging along nicely
Your computer spends most of its time running programs. That’s its job. If you’re not certain what it means to run a program, let me explain. Programs are a sequence of instructions to a computer. They are written using a programming language and look something like this:
input list let done = false let i = 0 if list is empty output "List is empty." else start loop let i = i + 1 output element i from list restart loop if i is not 3 end if let done = true
Each line in this example is an individual instruction. A computer goes through them step-by-step executing each one in turn. Eventually there will be no more instructions left. At this point the computer reaches the end of the program and the whole process finishes.
Simple, yes? Well, okay, it’s a bit more complicated than that. Let me draw an analogy.
Imagine a car. Normally when driving, a car chugs along the road taking each yard of the journey as it comes. You can draw an analogy between that and a computer executing a linear series of instructions one at a time. The first three lines of the example program are like that. The computer running the program simply goes from one line to the next doing as it’s told.
A programming language for driving a car might look something like this:
drive 10 metres change gear up drive 10 metres
But sometimes when driving, one has to make a decision. When a driver comes to a T-junction, they stop and decide whether to turn left or right. In computer parlance this is called a conditional. There’s one in the example at line 3 (the if-statement). When the computer encounters a conditional, it’s no longer just following orders - it now has to make a decision. Specifically it has to decide which of the subsequent lines to execute and which to skip over, just as a car must choose which direction to go in. In the example program, the computer will either print a message (“List is empty.”) or it will jump immediately to the line following the “else”, depending on whether the list is empty or not.
In our driving programming language, we would write it something like this:
if destination is Smeggerton turn left else turn right end if
This brings us to the construct in a computer program called iteration, which allows the program to instruct a computer to execute a group of instructions repeatedly. The example above has an iteration at lines 7 through 10, which goes through all the things in the list and outputs each.
It’s a bit like going round a roundabout in a car. Of course, the driver needs to know when to leave the roundabout, i.e. which exit to take, otherwise they’ll keep looping round it. Similarly, a loop in a program requires an exit condition that tells the computer when to stop looping and move onto the next instructions. From the exit condition in the example program (
restart loop if i is not 3) we can see that the computer will stop looping after three iterations because the variable i begins with a value of 0 and is increased by 1 during every loop.
Translating this into our driving language, we can see what happens when the car is looking for the third exit.
move to next exit check the exit leave roundabout if current exit is desired exit restart loop
This all tells you basically what a program is. When things chug along nicely, the computer follows the steps of a program. But things can suddenly come to a grinding halt.
A lot of crashing and hanging
When a program crashes, it stops functioning properly, usually the result of doing something invalid. For example, the program might have attempted to divide by zero; such an operation makes no sense mathematically and there’s no way for a computer to deal with it. When a program attempts to do something invalid, your computers says, “Aw, hell naw!” and things come to an abrupt end.
While a program might freeze after attempting to do something invalid, more often than not it simply terminates and disappears from the screen. Your operating system, the ‘master’ program that runs all other programs, will probably stay running and should clean up any mess left around by the faulty program.
However if your operating system crashes then you’re in real trouble because there’s no other program around to rescue it. This normally leads to the infamous Blue Screen of Death… and possibly the computer being thrown out of a window by an owner who lost a day’s work.
Crashing stands in contrast to hanging, and it is more likely that hanging causes a program to freeze. In this situation, a program stops responding to input. That says nothing about whether the program is still doing something, or, if it is, whether it’s actually making any progress. This can leave you clueless when deciding between waiting for a response or killing the program because it’s hopelessly stuck.
So what’s going on behind the scenes when a program hangs?
Behind the scenes
There are several possible causes for a hanging program. As you’ll see, they’re not always fatal and can be the result of sloppy programming. In these non-fatal situations a program may become responsive again if you give it time. Let’s go through them.
Too much to do
When a program becomes unresponsive, it may simply be that the computer is overloaded. Giving a program too much data is like weighing down a car with too much luggage.
Your program could be instructing the computer to process lots of data all at once without checking for input from the user in the meantime. But if it takes more than several seconds to finish processing, this will have the effect of the program hanging. A well-written program would be more helpful. It would tell the computer to concentrate on processing the data, but also occasionally (perhaps once a second) inform the user how things are coming along. That’s what happens when you see a progress bar: the computer is being kept very busy with a lot of heavy lifting, but still considerate enough to keep the user informed how far through the task it has come.
The program might also disable the user interface temporarily to make it clear that the program is too busy to accept any input for the moment.
What can you do if this is the cause of the problem? Try giving the program less data to work with all at once. For example, if you chose a large number of files as input, try again with fewer and see if the program responds quicker.
Another possible cause for a computer hang is getting stuck in an infinite loop. This happens when the exit condition of a loop is never met and the computer keeps executing the same instructions repeatedly. If the loop contains no instructions for interacting with the user then the program will never get a chance to accept input or give output and will hang.
Going back to our driving analogy, imagine the car comes to a roundabout. The directions instruct it to go around the roundabout until it comes to the fifth exit, which it should take. However, there’s a mistake in these instructions because the roundabout has only three exits. Interpreting them literally means the car will never get off the roundabout. Instead, it will go past the first three exits and come back to the entrance (or fourth exit) and reset its counting. Since the instructions say go around the roundabout until you come to the fifth exit, the car is doomed to keep going in a loop forever because it will never meet the exit condition. It’s still running, but it’s making no progress.
What can you do about this? Unfortunately this is a bug in the program. Look for an updated version of the program that fixes the problem, or report the bug to the program’s author.
Waiting for I/O
Another common cause of hanging results when the computer needs to work with some external piece of equipment, or peripheral. A lot of the time, the computer is doing work in its own head, the Central Processing Unit (or CPU), but it also needs to interact with the outside world. It has to perform tasks like reading information from memory or saving data to a disk drive. These are called input/output, or I/O, operations.
The CPU is capable of doing work much faster than its peripherals, so when for example the computer saves something to a disk, the CPU is left twiddling its thumbs. A poorly-written program will just wait until the operation completes, which means it won’t output progress and it won’t respond to input. If it takes a long time to save everything, your program will hang.
It’s like the driver of the car occasionally having to find their bearings. When they get lost, they consult a map. If the map is open to the correct page, the driver might only need to stop briefly (if at all) to find their position. However, if required page needs searching for, the driver must stop the car and start flicking through the book until its found. To us as outside observers, we don’t know why the car has stopped. Eventually it will continue if we’re patient, but we don’t know that for certain.
What can you do about this? Find an updated or alternative program that gives better user feedback; find which peripheral is being used and buy a faster replacement.
A special case of I/O slowing things down is called thrashing. In a sense, this problem occurs when the computer spends so much time doing internal housekeeping that it ends up neglecting the program it was given to execute.
This is known to happen during a process called paging. Because the CPU can access information in memory faster than if it were on a disk, the computer will try to keep all the information it needs in memory. However, memory sizes are nearly always much smaller than disk sizes, so the computer has to carefully choose which pieces of information get loaded into memory and which stay on disk for use later.
When your program instructs the computer to load some information, the computer will sometimes looks in memory to find it isn’t there. This is called a page fault. The computer then has to temporarily stop running your program, find the information on disk (which takes time) and find a place in memory to store it, before it can resume. All being well, this doesn’t take too much time and you don’t notice the delay.
But things are not always well. Several things could make the handling of a page fault extremely slow. For example, if the computer’s memory is too small, it can be the case that all of the frequently-used information doesn’t fit into memory at the same time. The more of this information is missing, the more time the computer spends searching through the disk. When things get really bad, the computer enters a state of thrashing where it spends almost all its time handling page faults. Your program gets little or no attention which means it hangs.
It is again as though the driver is dealing with a map, or in this case several maps. The current map sits handily on the top of a pile on the passenger seat and so long as the driver remains on this map, things are good. But as soon as they run off that map, they will have to stop and search through the pile for a new map. When the driver cannot get moving because the maps are in a mess, they’re in a state akin to thrashing.
What can you do about this? Increase your computer’s RAM; run fewer programs at once.
Sharing the road: multitasking
Most of the stuff in the previous section makes no assumptions about how many programs are running simultaneously. Those problems could crop up on just about any computer, even the old microcomputers of yesteryear which could run only one task at at time.
But almost any computer you’re likely to encounter today will be a multitasking device and they bring with them their own class of problems that can cause a computer to hang.
One of the deadliest problems in a multitasking system is deadlock. This occurs when two processes are both in a state whereby the condition for each being able to finish is that the other process finishes first; A is waiting B to finish, but B is also waiting for A to finish. The result? Like two painfully shy people secretly in love with each other, both wait endlessly and unknowingly for the other to make a move.
It’s important to note that the processes are waiting. Neither has crashed. They are each doing something, it’s just that all they are doing is constantly checking to see if they are able to proceed. They don’t get the opportunity to check whether the user has typed or clicked something and therefore can’t respond to inputs.
Our ongoing car analogy can help us here and because we’re multitasking, we have to add another car to the road. You can think of two processes in deadlock as two cars at a crossroads. Both come from opposite directions and want to turn left. When they meet in the middle, the driver of car A thinks, I’ll wait for the other car to turn first, then I’ll go. But the driver of car B has the exact same thought. Both are waiting for the other to complete their turn, resulting in neither car being able to proceed.
Deadlock usually happens in multitasking systems because processes are sharing resources, particularly resources where only exclusive access is allowed. Writing to a file is an example of this (only one program is permitted to alter a file at once). When your deadlocked program hangs, the root cause could be that while it is currently updating the accounts file, it then decides that it also needs to update the personnel file. However a second program might already have access to the personnel file, so your program has to wait. At this point the second program might decide that it also wants access to the accounts file. Seeing that your program is already using it, the second program has to wait. Without intervention, both programs will continue to wait forever without acknowledging any of your inputs and will therefore hang.
Luckily, interventions are possible.
An example solution: Windows
If you’ve used Windows, you’ve probably had this experience: a program suddenly stops responding despite your firm assurances you’d like to communicate (a.k.a. bashing the keyboard). Suddenly, this pops up:
Windows has actually detected your hanging program. How did it do this?1
When a program runs in Windows it makes a promise to the operating system that it will respond to all inputs within five seconds. Windows then monitors every input you give to the program to make sure it keeps this promise. As soon as Windows detects an input that goes unanswered for more than five seconds, it intervenes and pops up that (sadly) familiar message about the unresponsive program. If you choose not to wait, Windows will force the program to close.
Now it’s time to cross your fingers, restart the program and hope you didn’t lose your data. You do save regularly, don’t you?
References and Notes