Fundamentals 19 min read

Why Linux Cache Isn’t Always Free Memory: A Deep Dive into Buffers, Page Cache, and Shared Memory

This article explains how Linux’s free command reports memory usage, clarifies the roles of buffer and page caches, demonstrates which caches can be reclaimed, and shows why tmpfs, shared memory, and MAP_SHARED mmap allocations remain in cache until explicitly released.

21CTO
21CTO
21CTO
Why Linux Cache Isn’t Always Free Memory: A Deep Dive into Buffers, Page Cache, and Shared Memory

Introduction

In Linux systems the free command is commonly used to view memory usage. On a RHEL6 system the output shows large numbers because the default unit is kilobytes. Understanding the output can be divided into three levels of comprehension.

People who do not understand assume the system is using too much memory.

People who think they understand recognize that buffers and cached memory can be reclaimed.

People who truly understand know that the free output alone does not tell whether the cached memory is actually free.

Most Linux users fall into the second level, believing that buffers and cached memory are always reclaimable. Before proving this, we briefly define what buffers and cached memory mean.

What Is Buffer/Cache?

In Linux memory management, buffer refers to the buffer cache and cache refers to the page cache . Historically, buffer cache cached writes to block devices, while page cache cached reads. Modern kernels use page cache for memory pages and buffer cache for block‑device caches.

What Is Page Cache

Page cache stores file data for read/write operations and is also used by mmap to map files into memory. It handles most block‑device file caching.

What Is Buffer Cache

Buffer cache is used when the kernel reads or writes block devices, such as during filesystem formatting. It works together with page cache: when a file is written, page cache is updated and buffer cache marks the modified blocks for efficient write‑back.

How to Reclaim Cache?

When memory is low, the kernel reclaims memory, primarily by freeing buffer/cache. However, clearing cache incurs I/O cost because the kernel must write dirty pages back to disk before releasing them.

Cache can be manually cleared via /proc/sys/vm/drop_caches:

# echo 1 > /proc/sys/vm/drop_caches   # drop pagecache
# echo 2 > /proc/sys/vm/drop_caches   # drop slab objects (dentries, inodes)
# echo 3 > /proc/sys/vm/drop_caches   # drop both pagecache and slab

Can All Cache Be Reclaimed?

Not all cache is reclaimable. The first case is tmpfs files, which occupy cache until the file is deleted.

# mkdir /tmp/tmpfs
# mount -t tmpfs -o size=20G none /tmp/tmpfs/
# dd if=/dev/zero of=/tmp/tmpfs/testfile bs=1G count=13
# free -g   # cached increases by 13 GB
# echo 3 > /proc/sys/vm/drop_caches
# free -g   # 13 GB remains cached because the tmpfs file still exists
# rm /tmp/tmpfs/testfile
# free -g   # cache is released

The second case is shared memory (shm) . A program that creates a large shared memory segment using shmget increases the cached memory, and the cache is not reclaimed until the segment is removed with ipcrm or shmctl(..., IPC_RMID).

# ipcs -m   # list shared memory segments
# ipcrm -m 294918   # remove segment
# free -g   # cached memory returns to normal

Shared memory is implemented on top of tmpfs, so its behavior mirrors tmpfs.

The third case is memory obtained via mmap with the MAP_SHARED flag. Such mappings also use cache and remain unreclaimable until the process calls munmap.

# dd if=/dev/zero of=mmapfile bs=1G count=2   # create backing file
# ./mmap &   # allocate 2 GB MAP_SHARED mmap
# free -g   # cached grows by 2 GB
# echo 3 > /proc/sys/vm/drop_caches
# free -g   # cached unchanged while program runs
# (after program exits)
# free -g   # cached returns to previous level

Conclusion

Through three experiments we discovered that Linux cache is not always free memory:

Reclaiming file cache triggers high I/O because dirty pages must be written back.

Files stored in tmpfs occupy cache until the files are deleted.

Shared memory created with shmget or mmap (MAP_SHARED) occupies cache and is only released when the segment is removed or unmapped.

Both shmget and MAP_SHARED mmap are implemented via tmpfs, so they share the same cache behavior.

Understanding these details helps you interpret the free command more accurately and assess whether your system’s memory usage is truly optimal.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

CacheMemory ManagementLinuxmmapshared memorytmpfspage cache
21CTO
Written by

21CTO

21CTO (21CTO.com) offers developers community, training, and services, making it your go‑to learning and service platform.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.