Last updated: 11 June 2021

In my last article I looked at how the Linux kernel manages memory. This article covers the memory information shown in the free and top utilities.

Memory information in free

The free utility gets its data from /proc/meminfo. The file shows lots of data and is difficult to read by humans. That is where free comes in. It picks the most relevant fields and formats them so that the data is easier to read. It also has some options to format the output. For instance, the -h (--human) option uses mebi and gibibytes rather than kibibytes:

$ free -wh
               total        used        free      shared     buffers       cache   available
Mem:            30Gi       3.6Gi       7.8Gi        35Mi       3.0Mi        19Gi        26Gi
Swap:          8.0Gi        10Mi       8.0Gi

There are a few things to note. The first is that free shows two types of cached memory: buffers and cache. Both are part of the page cache, and unless you use the -w (--wide) option free lumps them together. They are different though. Buffers map pages in memory to blocks on the disk. You can think of buffers as metadata (i.e. what is the inode on disk for this memory page). The cache is the actual data (i.e. the contents of a file that has been loaded into memory). Typically, the buffer is very small.

The used column is the total amount of memory minus the free, buffers and cache columns. In other words, the page cache is not part of the amount of used memory. This makes sense, as the kernel can evict pages from memory at any time. If a process suddenly wants a huge chunk of memory then the kernel can simply reduce the cache.

The free column shows unused memory. This number is likely to be low, and it should be. Unused memory is wasted memory. Rather than just sitting there it could be used to cache some more stuff! The last column (available) shows the actual amount of memory that is available for new processes.

Memory information in top

By default, top sorts its output by CPU usage. You can sort the output by memory by hitting the M key. Also, you can use the e key to display the data in different units (i.e. mebibytes rather than kibibytes).

The memory columns are quite different from the ones shown by free:

  • VIRT is the total amount of memory used by and reserved for the process. This includes memory shared with other processes and files that are used by the process. The amount is always greater than the actual memory usage (RES).
  • RES is the actual amount memory used by the process. This is the number you are interested in. It is also the number that is used to calculate the percentage shown in the %MEM column.
  • SHR is the amount of memory that is shared with other applications.

Overcommitting memory

It is useful to understand that the virtual memory is the amount of memory promised to the process by the kernel. The actual usage is likely to be a lot less, and the kernel therefore overcommits memory. This is much like a restaurant taking more bookings than it has tables. Restaurants can be fairly sure that some diners don’t turn up. To make the most use of the available tables they can therefore overbook a couple of tables.

Overcommitting can be configured via sysctl. By default, /proc/sys/vm/overcommit_memory is set to 0:

# sysctl vm.overcommit_memory
vm.overcommit_memory = 0

This configuration allows a modest amount of overcommiting and is suitable for most servers. For specific workloads it can be beneficial to tweak the setting. If you want to learn more, the setting is described in the kernel documentation. As always, you can of course also contact us if you have any questions around the memory usage on your server.