1. Overview
In this tutorial, we’ll explore four memory measurements used by processes in Linux; VSZ, RSS, USS, and PSS.
Each has its own characteristics and usages, as we’ll see when we go into details.
2. VSZ Memory
VSZ is short for Virtual Memory Size. It’s the total amount of memory a process may hypothetically access.
It accounts for the size of the binary itself, any linked libraries, and any stack or heap allocations.
When a process is started, VSZ memory becomes RSS memory, over which we’ll go now.
3. RSS Memory
As opposed to VSZ, RSS, also short for Resident Set Size, is a measurement that shows how much RAM has been allocated to a process during its execution.
But, it isn’t actually an accurate measurement for RAM usage for a process since it doesn’t take into account libraries already loaded in memory.
If two processes use one or more libraries, then RSS will report the libraries’ sizes for each process, even though the libraries would be already loaded beforehand in the case of one process starting after another. This is why RSS can be misleading and shouldn’t be trusted completely.
Because RSS shows the whole memory output, even for information that has already been preloaded, if we add up everything in the processes list, we’d get more memory than the total memory allocated.
4. Using RSS and VSZ
4.1. Using ps
One of the ways to check the RSS and VSZ for Linux processes is to call ps:
$ ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.1 0.0 169316 13184 ? Ss 18:14 0:04 /sbin/init splash
root 2 0.0 0.0 0 0 ? S 18:14 0:00 [kthreadd]
root 3 0.0 0.0 0 0 ? I< 18:14 0:00 [rcu_gp]
// ...
root 28 0.0 0.0 0 0 ? S 18:14 0:00 [idle_inject/3]
The output above is just a fraction of all the processes listed in the terminal.
But as we can see, we have two columns named RSS and VSZ, which show the total memory allocated to each process and the maximum a process has assigned to itself.
If we want to see only some processes (for example all Google Chrome processes), we can use:
ps eo user,pid,vsz,rss $(pgrep -f 'chrome')
USER PID VSZ RSS
baeldung-reader 5236 1358620 333984
baeldung-reader 5246 268300 63804
baeldung-reader 5247 268300 63084
// ...
baeldung-reader 36354 4587872 52700
4.2. Using top
Another useful command to check on processes is top. When we use it, it’ll display all the processes running in our system.
Unlike the command above, it checks every time for changes in the list of processes that run, so we can see changes in RSS and VSZ in real-time.
For example, if we look at the process with the PID 12408 (google chrome instance in this case), we can see the differences in, for example, %CPU which shows how much of the CPU that particular process is using. As we can see in the terminal, there are multiple chrome processes that run and it makes sense because there really are multiple processes that run – the actual chrome application, the opened tabs, maybe some downloads through the browser downloader, etc. – which are allocated more or fewer resources as the CPU sees fit:
top - 22:55:50 up 4:41, 1 user, load average: 0,82, 2,25, 2,72
Tasks: 350 total, 1 running, 349 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0,5 us, 0,2 sy, 0,0 ni, 99,3 id, 0,0 wa, 0,0 hi, 0,0 si, 0,0 st
MiB Mem : 32035,2 total, 23820,8 free, 3484,8 used, 4729,7 buff/cache
MiB Swap: 0,0 total, 0,0 free, 0,0 used. 27832,6 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
// ...
12408 baeldung-reader 20 0 9146156 312452 119532 S 1,7 1,0 9:56.70 chrome
// ...
12077 baeldung-reader 20 0 4784576 182196 92716 S 0,3 0,6 1:00.59 chrome
And 30 seconds later:
top - 22:56:20 up 4:41, 1 user, load average: 0,63, 2,07, 2,65
Tasks: 351 total, 1 running, 350 sleeping, 0 stopped, 0 zombie
%Cpu(s): 1,8 us, 0,5 sy, 0,0 ni, 97,7 id, 0,0 wa, 0,0 hi, 0,0 si, 0,0 st
MiB Mem : 32035,2 total, 23806,6 free, 3492,9 used, 4735,7 buff/cache
MiB Swap: 0,0 total, 0,0 free, 0,0 used. 27819,3 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
// ...
12408 baeldung-reader 20 0 9185940 306080 123896 S 14,0 0,9 10:00.01 chrome
// ...
4340 baeldung-reader 20 0 1171680 328412 156400 S 1,3 1,0 6:15.76 chrome
// ...
4579 baeldung-reader 20 0 4723180 172064 73352 S 0,7 0,5 0:23.38 chrome
// ...
4414 baeldung-reader 20 0 377528 105756 66972 S 0,3 0,3 1:33.44 chrome
4457 baeldung-reader 20 0 431860 120172 86228 S 0,3 0,4 20:52.63 chrome
12691 baeldung-reader 20 0 4737484 173728 99572 S 0,3 0,5 0:15.66 chrome
// ...
Again, this is just a fraction of the output, but we can see the volatility in change and the processes that are ordered out by the CPU which are prioritized and deprioritized.
As we mentioned before, these types aren’t completely accurate, but we can get a reliable estimate.
5. PSS Memory
PSS, or Proportional Set Size, is a much more useful memory management metric. It works exactly like RSS, but with the added difference of partitioning shared libraries.
For example, if we have five processes using the same library with a size of 50 pages, for each process the size reported by PSS will have only 10 pages for that particular shared library. The same thing happens for all shared libraries for all shared processes.
One advantage of PSS is that summing all the processes together, we get a good approximation of the whole memory usage in a system.
6. USS Memory
The Unique Set Size, or USS, represents the private memory of a process. In other words, it shows libraries and pages allocated only to this process.
This type of memory is also very useful, as it represents the actual cost of launching another process. And, vice versa, when a process ends, it represents the actual amount that is returned to the system.
7. Using PSS and USS
7.1. Using ps
To check the PSS memory on a Linux process, we have to access the /proc/{$PID}/smaps of the process we want to check. For this, we need the PID of the process we want to check.
For example, if we want to check on the rabbitmq-server process:
$ ps -aux | grep 'rabbitmq-server'
rabbitmq 1055 0.0 0.0 2608 604 ? Ss iun04 0:00 /bin/sh /usr/sbin/rabbitmq-server
$ sudo cat /proc/1055/smaps | grep -w 'Pss:'
Pss: 20 kB
Pss: 76 kB
Pss: 24 kB
// ...
Pss: 0 kB
Here, we will see multiple PSS outputs, which if we add we obtain the total PSS print of the process. Or, instead of adding lots of numbers, we can do this:
$ sudo cat /proc/1055/smaps | grep -i 'Pss:' | awk '{Total+=$2} END {print Total}'
165
Here we have the total PSS memory size of the rabbitmq-server process reported in KB. If we have a process that uses lots of PSS memory, we can format the output to report it in a bigger measurement unit:
$ sudo cat /proc/1055/smaps | grep -i 'Pss:' | awk '{Total+=$2} END {print Total/1000" MB"}'
0,165 MB
We just need to remember to divide by 1000’s, not 1024’s because that’s the difference between Kilo and Mega.
7.2. Using smem
A very interesting tool we use to check for USS is smem, which we use to output USS and other types:
$ sudo apt-get install smem
$ smem
PID User Command Swap USS PSS RSS
4346 baeldung-reader cat 0 116 149 1936
4347 baeldung-reader cat 0 120 151 1884
2663 baeldung-reader /usr/libexec/gnome-session- 0 488 522 5240
2578 baeldung-reader /usr/libexec/xdg-permission 0 748 794 6320
2558 baeldung-reader /usr/bin/dbus-daemon --conf 0 668 812 4672
2820 baeldung-reader /usr/libexec/gsd-screensave 0 788 832 6404
2531 baeldung-reader /usr/libexec/ibus-memconf 0 776 859 7148
2803 baeldung-reader /usr/libexec/gsd-a11y-setti 0 832 885 6728
2551 baeldung-reader /usr/libexec/at-spi-bus-lau 0 824 893 7284
3192 baeldung-reader /usr/libexec/gvfsd-metadata 0 860 902 6376
2498 baeldung-reader /usr/libexec/gvfs-mtp-volum 0 860 906 6544
2431 baeldung-reader /usr/libexec/gvfs-goa-volum 0 904 990 6644
To check a certain process, we make use again of the grep command:
$ smem | grep -w 'chrome'
60608 ioan grep --color=auto -w chrome 0 364 396 2588
4381 ioan /opt/google/chrome/nacl_hel 0 604 1121 4132
4376 ioan /opt/google/chrome/nacl_hel 0 668 1183 4204
4379 ioan /opt/google/chrome/chrome - 0 204 1232 15752
// ...
4340 ioan /opt/google/chrome/chrome 0 276260 290467 387636
8. Conclusion
In this article, we saw how we can use the different memory measurements of Linux processes.
We also learned when to choose one over another and what they mean.