RAM, Linux and You

One of the most fundamental parts of any operating systems is managing memory; the subsystem conveniently known as the Memory Management Unit or MMU. This subsystem is a very complex one but, fortunately for us, it's very well documented.

When we're talking about memory, it's usually the physical RAM that we're referring to. Total physical RAM is one of the most important attributes you'd look for in a new PC or server. But it's the operating system that's ultimately involved in how that RAM is used and distributed. The OS serves as an abstraction layer between applications and the physical memory. This layer divides the physical RAM into virtual "pages", which are the smallest units of data an OS can use. By default, the page size is 4KB in a Linux system, as working with each bit individually would be too complex to be efficient. 

When Linux uses system RAM, it creates a virtual memory layer to then assigns processes to virtual memory. Virtual memory is actually a combination of both RAM and swap space; swap space is a section of your hard drive designated as available for use in case usable RAM runs out. This extra abstraction layer is here so that each running process doesn't overlap and try to use memory already being used by another process. This also means that virtual memory can be expanded beyond the physical RAM capacity, which can be useful in a pinch even if it's not very efficient.

As mentioned before, a process is allowed access to a section of RAM by the operating system; the process has no control over memory allocation whatsoever. As a result, the devs that work on applications, especially when they're written in high level code, don't really worry about working with memory. 

Usually any file or part of a file system is mapped using the system command mmap, and is referred to as a memory mapped file. If a memory page file doesn't have any file associated with it, it's referred to as anonymous memory and ut's allocated using the "malloc" function. Using the way file mapped memory and anonymous memory are allocated, the operating system can have processes using the same files working with the same virtual memory page thus using memory more efficiently. 

Sometimes it happens that a process is occupying memory that's needed for another one. In this case, the OS uses the OOM (out of memory) killer. This utility chooses a process and reallocates its memory pages to other processes. In Linux, this OOM killer is enabled by default. Disabling it would basically leave your system with no recourse when it runs out of memory other than extending to the hard drive. 

"Cgroups" is a utility used to isolate a process to a specific memory address, which groups processes into logical groups and allocates an amount of memory to them. The inclusion of cgroups in Linux actually laid the groundwork for containers used today, such as Docker and OpenVZ. 

Linux is also capable of working with multiprocessor systems using NUMA (non-uniform memory access). What this does is attempt to allocate memory to processes running on the CPU closest to the physical RAM. 

To break down how ram is handled by Linux systems, let's look at a typical readout of its operational memory information:

$ sudo cat /proc/meminfo

MemTotal:        3789684 kB
MemFree:         1765616 kB
MemAvailable:    3051416 kB
Buffers:          134112 kB
Cached:           990372 kB
SwapCached:            0 kB
Active:          1190556 kB
Inactive:         579688 kB
Active(anon):     646244 kB
Inactive(anon):     7252 kB
Active(file):     544312 kB
Inactive(file):   572436 kB
Unevictable:           0 kB
Mlocked:               0 kB
SwapTotal:             0 kB
SwapFree:              0 kB
Dirty:              1936 kB
Writeback:             0 kB
AnonPages:        645756 kB
Mapped:           141264 kB
Shmem:              7740 kB
Slab:             214240 kB
SReclaimable:     197816 kB
SUnreclaim:        16424 kB
KernelStack:        2960 kB
PageTables:        17536 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:     1894840 kB
Committed_AS:    1601240 kB
VmallocTotal:   34359738367 kB
VmallocUsed:        9668 kB
VmallocChunk:   34359720912 kB
HardwareCorrupted:     0 kB
AnonHugePages:         0 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
DirectMap4k:       79820 kB
DirectMap2M:     2803712 kB
DirectMap1G:     1048576 kB

So let's go over what all this means, one by one.

MemTotal - as it implies, this is the total physical memory the system can see.
MemFree - displays available memory currently not used for any process.
Buffers - memory that's storing information currently waiting to be written to the hard drive. This allows processes to continue working with data without waiting for it to be written to disk.
Cached - the amount of memory taken up by file, database, process or device caches.
SwapCached - data that was written to a swap file that has then been moved back to RAM, but continues to exist in the swap file.
Active - volume of memory that's being frequently used by processes. As such, this section of memory is rarely free.
Inactive - memory that's occupied but not actually being used; this section of memory has priority for being written to a swap file if the need comes up.
Unevictable - for whatever reason, these pages can't be moved to swap.
Mlocked - memory that's allocated using the mlock function.
SwapTotal and SwapFree - same idea as MemTotal and MemFree; total volume of the swap file and how much of it is available for use.
Dirty - changed memory pages that are still occupying RAM but not yet written to disk.
Writeback - this is memory that's currently being written to disk. 
AnonPages - volume of anonymous memory.
Mapped - volume of memory allocated with mmap.
Slab - volume of pages allocated for smaller kernel structures
PageTables - memory allocated within tables.
NFS_Unstable - memory allocated to moving data over NFS v3+. 
Bounce - memory used for block devices.
CommitLimit - this is the total memory available to to be allocated based on the overcommit ratio. 
Committed_AS - volume of memory currently allocated by the operating system. 
VmallocTotal/VmallocUsed/VmallocChunk - a series of stats for virtual memory used by the kernel. 
HugePages_Total/HugePages_Free/HugePages_RSVD - series of stats for very large page files (huge).
Hugepagesize - amount of Huge page files.
DirectMap1G - memory allocated as Huge pages that are 1GB in size.

That about does it for our overview of how Linux handles memory. All of this is important to be aware of when trying to maximize server performance, and get the best value out of its production. If you are trying to make a Linux server work for you, try out ServerSuit (why not, first 30 days is free). Understanding how Linux uses memory lets you get the most out of using ServerSuit too. 

Until next time!

Follow ServerSuit on Twitter and Facebook

This article was originally published Jun 2018

July 03 2021

Add or review comments

Please leave your comment

Existing comments

Comments 0