Inspect and manage processes with ps

Understanding Linux process management can be useful for both developers and system administrators. The ps command is an excellent way to get information about processes running on the system.

What is a process?

A process is a series of tasks executed by the operating system. In most cases the tasks are defined in a computer program (a set of instructions). The result of the execution of these programs are processes. Since Linux is a multiprocessing operating system, processes can be run concurrently and independently from each other. Each process has its own permissions, virtual memory address space, and so on.

A process can access and use system resources such as memory, CPUs, files on the file system, and physical devices. To manage and control access to these resources, the kernel needs to keep track of which processes are running and which resources are in use. The kernel does this using a data structure to represent the processes. This data structure is quite large and complex, so this article only focuses on a few categories of information.


Each process can be in one of the following states: RUNNING, WAITING, STOPPED or ZOMBIE. RUNNING and STOPPED are relatively straightforward to understand. The WAITING state means the process is waiting for an event or to access a resource , such as waiting for keyboard input. The ZOMBIE state describes a process which for some reason is stopped but still present in the list of processes managed by the kernel.


Each process in the system has a process identifier, or PID. Process also have user and group identifiers used to control access on the system resources.


Each process except for the initial one has a parent process. The kernel keeps track of the hierarchical relationship between processes.

File system

This category is used to track access to any files a process has opened.

Virtual Memory

This category is used by the kernel to track the mapping of each process’ virtual memory onto the system’s physical memory. A process’ virtual memory is a virtual address space that contains executable code and the data from different sources. For example, when a program uses a shared library, the code and data from the library is linked to this process’ virtual memory. Another example is for a program to allocate virtual memory during processing, such as to hold the content of files that it is reading.

ps in action

Now that you have a better idea of what a process is, here’s a look at the ps command and how to use it to get information about our system’s running processes. To quickly print all the active processes, use the following command:

$ ps -ef 
root         1     0  0 20:31 ?        00:00:03 /usr/lib/systemd/systemd --switched-root --system --deserialize 24
root         2     0  0 20:31 ?        00:00:00 [kthreadd]
root         4     2  0 20:31 ?        00:00:00 [kworker/0:0H]

Note the use of the -e option to display all processes, and -f to display the full format. You can also use -F for extended full format. The full format prints these eight columns:

  • UID = user identifier
  • PID = process identifier
  • PPID = parent process identifier
  • C = CPU utilization
  • STIME = time when the process started
  • TTY = terminal
  • TIME = combined system and user CPU time used by the process so far
  • CMD = process name including command

You can also see that systemd, which is the initial process, has a parent PID of 0. As the initial process, it has no parent.

The extended full format adds three more columns to the displayed output:

$ ps -eF
root         1     0  0 57658 11988   3 20:31 ?        00:00:03 /usr/lib/systemd/systemd --switched-root --system --deserialize 24
root         2     0  0     0     0   0 20:31 ?        00:00:00 [kthreadd]
root         4     2  0     0     0   0 20:31 ?        00:00:00 [kworker/0:0H]
root         6     2  0     0     0   0 20:31 ?        00:00:00 [mm_percpu_wq]

The new columns are:

  • SZ = virtual memory usage
  • RSS = real memory usage (resident set size)
  • PSR = processor to which the process is currently assigned

You can also customize the output of the ps command. Use the -o option to specify which columns you would like to be displayed. This can be useful when using ps in a shell script.

$ ps -ef -o pid,cmd
1   /usr/lib/systemd/systemd --switched-root --system --deserialize 24
2   [kthreadd]
4   [kworker/0:0H]

Another useful option is -u, which allows you to filter the processes displayed by user ID. For example, to display all the processes owned by the user root, run a command like this:

$ ps -u root -o user,pid,cpu,cmd 
root         1   -   /usr/lib/systemd/systemd --switched-root --system --deserialize 24
root         2   -   [kthreadd]
root         4   -   [kworker/0:0H]
root         6   -   [mm_percpu_wq]
root         7   -   [ksoftirqd/0]

Another example to print the processes owned by the gdm user.

$ ps -u gdm -o user,pid,cpu,cmd
gdm       1126   - /usr/lib/systemd/systemd --user
gdm       1139   - (sd-pam)
gdm       1157   - /usr/libexec/gdm-wayland-session gnome-session --autostart /usr/share/gdm/greeter/autostart
gdm       1180   - /usr/bin/dbus-daemon --session --address=systemd: --nofork --nopidfile --systemd-activation --syslog-only
gdm       1194   - /usr/libexec/gnome-session-binary --autostart /usr/share/gdm/greeter/autostart

Debugging using ps

The ps command comes in handy when debugging an application. More specifically, you can use it to determine the resources used by an application. To list all the threads for a particular process, run a command like this:

 $ ps -C firefox -L -o pid,tid,pcpu,state,nlwp,cmd 
 3015 3015 7.6  S 69   /usr/lib64/firefox/firefox 
 3015 3040 0.0  S 69   /usr/lib64/firefox/firefox 
 3015 3041 0.0  S 69   /usr/lib64/firefox/firefox 
 3015 3042 0.5  S 69   /usr/lib64/firefox/firefox 
 3015 3043 0.3  S 69   /usr/lib64/firefox/firefox 
 3015 3044 0.0  S 69   /usr/lib64/firefox/firefox

This example uses the -C option to select the processes using the command name firefox. The -L option shows the threads for that process. The -o option again displays selected columns, in this case PID and CMD, along with some other new columns:

  • TID = thread identifier
  • PCPU = percentage of CPU usage
  • STATE = state of the process, as seen earlier in this article. In the example the threads are in the S state, which means interruptible sleep — these processes are waiting for an event to run.
  • NLWP = number of light processes; in the example above, firefox is using 69 threads

Finally, you can use ps to track a memory leak. The presence of a memory leak in a process would increase the RAM memory the process has. You can monitor the Resident Set Size (RSS) to have an idea of how much RAM memory a process is using.

$ ps -eF --sort -rss
3015 2352 11 807180 761056 3   14:20 tty2 00:06:47 /usr/lib64/firefox/firefox
3152 3015 7  611589 394944 0   14:20 tty2 00:04:23 /usr/lib64/firefox/firefox
3087 3015 1  598306 350224 0   14:20 tty2 00:00:40 /usr/lib64/firefox/firefox
3715 3015 2  579774 314300 1   14:44 tty2 00:00:46 /usr/lib64/firefox/firefox
2352 2235 2  921991 228908 1   14:15 tty2 00:01:50 /usr/bin/gnome-shell

This command makes use of the –sort -rss option to show the process with the highest RSS at the top. You could sort the processes in the other direction (increasing RSS) using the following option –sort rss.

Photo by João Silas on Unsplash.

For Developers For System Administrators Using Software


  1. Cody

    ‘Finally, you can use ps to track a memory leak. The presence of a memory leak in a process would increase the RAM memory the process has. You can monitor the Resident Set Size (RSS) to have an idea of how much RAM memory a process is using.’

    Ehm, no. It indicates there was a request for more memory (or memory at all). A process using more memory doesn’t equate to a memory leak; it equates to requesting more memory. Correlation does not imply causation. That’s all there is to it. Even if there is a memory leak it won’t show you where in the code there is and – critically is this: there is such a thing as sharing memory so just because you think it should be free()d doesn’t mean it should be. A memory leak doesn’t mean what you’re implying at all. If that was the definition of a memory leak every application would have memory leaks – and it would potentially make naïve programmers try to ‘fix’ it when it’s not needed and more than likely cause major problems. Memory bugs can be incredibly difficult to track down and fix depending on what specific type of memory bug but a memory leak isn’t using more memory. I have no idea where or how you got that idea but it’s wrong. I could explain it but I have to run so I’ll just refer you to Wiki:

    • Renê

      The author is simply pointing out one of the many ways to investigate resource utilization. ‘Correlation does not imply causation. ‘ and that’s why the content in the quote is correct:

      ‘Finally, you can use ps to track a memory leak. The presence of a memory leak in a process would increase the RAM memory the process has. You can monitor the Resident Set Size (RSS) to have an idea of how much RAM memory a process is using.’

      If we had it in a different order like: ‘An increase in the RAM memory a process has would imply in the presence of a memory leak in the process .’ we should point out the problem. What you did is a common straw man fallacy (refuting an argument that was not presented by that opponent), I’ll refer you to the Wiki:

      • Azu

        @Rene. Nice rebuttal. Classy.

      • Cody

        The point is you cannot track a memory leak with ps. There are other subtleties to consider too. See for example and here for two examples of others.

        But as for your supposed point the keyword is ‘track’. The point of tracking something is knowing where it is (if that’s even what it is – often it isn’t) and you simply don’t. Besides it could be a library are you sure it’s not about to free() the memory? The point also is it’s incredibly naïve to ‘track’ a memory leak that way. Only ignorant person would try it that way and frankly it’s jumping to conclusions that there is a memory leak at all (which is arguably just as silly is optimising when there is no need to do so); there are reasons there are entire tools to do it and there is a reason there are wrappers to the malloc() family for this type of thing: because it’s not as simple as look at RSS/VSZ. That should be obvious.

        Track meanwhile means this as a verb: ‘Follow the trail or movements of (someone or something), typically in order to find them or note their course.’ But sure if you want to waste your time tracking imaginary memory leaks through ps, by all means – have fun with it.

        • Zlatko

          It’s obvious that this isn’t about tracking memory leaks. It’s more about ps being a tool that can help identify memory hogs, or perhaps a memory leak at a glance.
          E.g. I run ps on a server and I see that RSS/vsz for glasfish or some other VM is at the top of what I have allotted it. In certain cases, it can help signify that there is a memory leak in one of the applications running in the VM.

          So while it’s obvious that this isn’t gdb and won’t find your bugs for you, it was also obvious, to me at least, that the author of the article referred to ps here simply as a tool to, at a glance, in certain cases, that can quickly identify which of your processes is a memory hog and therefore, if that’s unexpected, mark it for deeper inspection with proper tools.

  2. alzaim

    This very useful. thank you very much

Comments are Closed

The opinions expressed on this website are those of each author, not of the author's employer or of Red Hat. Fedora Magazine aspires to publish all content under a Creative Commons license but may not be able to do so in all cases. You are responsible for ensuring that you have the necessary permission to reuse any work on this site. The Fedora logo is a trademark of Red Hat, Inc. Terms and Conditions