Determine which processes are consuming the most CPU

TODO: is this section header okay? "process is" versus "processes are"

  • No, we definitely need one of the above. I suggest "processes are" --ceri

I concur, and had the gall to make the change ;-). Now, do we not also need "cycles" at the end? ---KevinDKinsey

Author: hubertf contact BSD flavour

Reviewer: ceri ceri@FreeBSD.org FreeBSD|OpenBSD

Reviewer: name contact BSD flavour


Concept

Be able to view active processes and recognize inordinate CPU(((CPU))) usage. In addition, know how to end a process or change its priority.

Introduction

There are several programs that allow showing CPU utilization on a Unix system. Some of them can be found on every kind of system, some are specific to others. Here's a list:

  • ps(1)(((ps))): The command is available on all Unix systems, but the evil thing is that the set of options differs between systems. The good news is that all BSD systems use the same set of options, and by running "ps -aux" the list is sorted to have the process using the most CPU time on the top.

  • top(1)(((top))): This interactive command is not available on all Unix systems, but it's part of every BSD system. Running it will display some system statistics on the top of the screen, and then provide a list of processes that's sorted by CPU utilization by default. The display is updated every few seconds, so any process that starts hogging the CPU can be determined easily.

  • systat(1)(((systat))): This program can only be found on BSD systems. It can display a wide range of system statistics, and the default is to display processes and their CPU utilization. Unfortunately no process ID is shown, so if a certain process misbehaves some other method needs to be used to precisely determine the guilty party.

Now that we know how to determine general process stats, managing them should be discussed. For that, processes need to be identified, which is done via a process ID (PID)(((PID))) that is unique for each running process on a system. The above programs, with the exception of systat(1)(((systat))), can be used to determine the PID of a running process.

Operations that can be done on processes include:

  • change priority: this is usually done using the renice(1)(((renice))) program or shell builtin. The priority there is given as a "niceness" level(((nice-level))), which goes from -20 (not nice at all, the highest priority) to 20 (very nice, or the lowest priority). Nice levels below (i.e., priorities higher than) 0 are reserved for the superuser, and a non-superuser process that has had its nice level increased (and therefore its priority decreased) cannot undo this change later.

  • start with different priority: If a process is known to need less or more CPU time than is assigned by default, it can be started with a different nice level. This is done using the nice(1)(((nice))) command.

  • abort the process: there are several commands that can be told to a process, by sending it a certain "signal". The command to send signals to a process is kill(1)(((kill))), and a list of possible signal names can be printed with "kill -l". See the signal(7) manpage for a description of the signals and their default handlers.

    Please note that a process can ignore most signals, or install a new handler to do whatever it likes to do with a signal. There's only one signal that can't be ignored, and which also doesn't give a process the chance to clean up after itself, SIGKILL(((SIGKILL))) (9). Be sure to only use this as a last resort, as unpleasant side-effects may happen! In most cases, the default of SIGTERM(((SIGTERM))) (15) is sufficient to end a process.

Examples

Determine the process that takes most CPU:

% ps -aux | head -3
USER      PID %CPU %MEM    VSZ   RSS TTY   STAT STARTED     TIME COMMAND
feyrer   5924 50.0  5.9 104588 30900 ttyp6 R+   12:17AM  0:03.31 qemu -m 64 -bo
root    25528 13.7  0.2    468  1104 ttyp4 R+   12:17AM  0:00.85 /usr/bin/find 

Now that we know qemu hogs the CPU, nice it down a bit. Running 'renice' without arguments will show its usage:

% renice
Usage: renice [<priority> | -n <incr>] [[-p] <pids>...] [-g <pgrp>...] [-u <user>...]

Let's say we want to change the nice level of process 5924 (qemu) from the default of 0 to 10:

% renice 10 -p 5924
5924: old priority 0, new priority 10

Upon observation we will still see that the process takes the most CPU:

% ps -aux | head -3
USER      PID %CPU %MEM    VSZ   RSS TTY   STAT STARTED     TIME COMMAND
feyrer   5924 27.1 11.6 104704 60636 ttyp6 RN+  12:17AM  0:31.38 qemu -m 64 -bo
feyrer   1206  1.9 10.8  73896 56304 ?     Ra   11:48AM 75:11.33 /usr/pkg/lib/f

This is because no other process claims the CPU. If another process (e.g. your windowing system, or a compile job) would claim the CPU, the qemu process would relinquish the CPU until no other job needs it.

If the command still uses too much CPU and you are very certain that there is no other way to end it (e.g. by properly ending it; in the case of Qemu by shutting down the system being emulated), it can be killed using the kill(1) command:

% kill 5924

If, for some reason, a process catches the default signal (SIGTERM, 15), a different signal number can be given to the kill(1) command either by name or by signal number that is known to terminate the process unconditionally - be very careful with this:

% kill -9 5924
% kill -KILL 5924

Both of the preceding commands have the same effect; they send the SIGKILL signal to the process with process ID 5924.

Practice Exercises

  • Determine a list of processes running on your systems using top(1), ps(1) and systat(1).
  • Determine which process consumes the most CPU time
  • Make sure the process is not critical to the system's operation, and lower its priority by increasing its nice-level
  • Try to increase the process' priority again, i.e. lower the nice-level, and see it fail during this operation.
  • Send the process the SIGTERM signal.
  • Possibly restart the process.

More information

top(1), systat(1), ps(1), nice(1), renice(1), kill(1). NetBSD only: signal(7)