Workloads such as Apache Spark can accumulate large amounts of page cache in a short time. Most of those pages are dirty pages, which are reclaimed slowly. If reclaim cannot free memory fast enough, the kernel runs out of memory and triggers an unexpected out-of-memory (OOM) error, causing business jitter. Page Cache Limit caps page cache usage per memory control group (memcg) and reclaims excess cache when the limit is exceeded, preventing both unbounded page cache growth and unexpected OOM errors. Available in Alibaba Cloud Linux 3 starting with kernel version 5.10.134-14.
Interfaces
The following table summarizes all interfaces. Detailed descriptions follow.
| Interface | Description | Default |
|---|---|---|
/sys/kernel/mm/pagecache_limit/enabled | Global on/off switch | 0 |
/sys/fs/cgroup/memory/<memcg>/memory.pagecache_limit.enable | Per-memcg on/off switch | 0 |
/sys/fs/cgroup/memory/<memcg>/memory.pagecache_limit.size | Page cache limit in bytes | 0 |
/sys/fs/cgroup/memory/<memcg>/memory.pagecache_limit.sync | Reclaim mode: async (0) or sync (1) | 0 |
/sys/kernel/mm/pagecache_limit/enabled
Controls the global switch for Page Cache Limit. Valid values: 0 and 1.
1: enables Page Cache Limit globally.0: disables Page Cache Limit globally.
/sys/fs/cgroup/memory/<memcg>/memory.pagecache_limit.enable
Controls the per-memcg switch. Valid values: 0 and 1.
1: enables Page Cache Limit for the memcg.0: disables Page Cache Limit for the memcg.
/sys/fs/cgroup/memory/<memcg>/memory.pagecache_limit.size
Sets the maximum page cache usage for a memcg, in bytes. Valid range: 0 to the value of memory.limit_in_bytes for the memcg.
0: disables Page Cache Limit for the memcg, regardless of the global switch or the per-memcg switch.Non-zero value: limits page cache usage of the memcg to this value.
Note: Page cache usage of a memcg is the sum of the page cache usages of all its child memcgs.
/sys/fs/cgroup/memory/<memcg>/memory.pagecache_limit.sync
Controls the reclaim mode. Valid values: 0 and 1.
0: asynchronous reclaim. The kernel offloads reclaim tasks to background workqueue threads, reducing impact on main threads. If a workload generates page cache faster than the workqueue can reclaim it, page cache may temporarily exceed the limit.1: synchronous reclaim. Reclaim runs in the context of the current process, blocking it until enough page cache is freed. This provides stronger guarantees but may cause process-level latency spikes.
How it works
After you enable Page Cache Limit, the kernel applies the following logic every time page cache is allocated to a memcg process:
Check the current memcg. The kernel determines whether the memcg has exceeded its page cache limit. It then traverses up the memcg hierarchy, checking the
memory.pagecache_limitvalues of each parent memcg. If a parent's value is0, the feature is disabled for that parent and all its descendants — page cache is unrestricted there.Select the reclaim mode. If the memcg has exceeded its limit, the kernel checks
memory.pagecache_limit.syncto decide between asynchronous and synchronous reclaim.Reclaim page cache. The reclaim behavior differs by mode:
Mode Reclaim targets Synchronous By default, unmapped file pages only. After more than four scans, mapped file pages are also eligible. Asynchronous By default, both unmapped and mapped file pages. After more than two scans, dirty pages are also eligible.
The following diagram illustrates the end-to-end flow:
Memory page types
| Type | Description |
|---|---|
| Unmapped file pages | Pages not mapped to any file. Typically hold private, temporary data that is not persisted to disk. |
| Mapped file pages | Pages mapped to files. Allow processes to read and write file data directly in memory. |
| Dirty pages | Mapped file pages that have been modified but not yet written back to disk. Reclaimed slowly because they must be flushed first. |
Configure Page Cache Limit
This example creates a 20 MiB page cache, enforces a 10 MiB limit, and then verifies that the feature reclaims the excess.
Prerequisites
Before you begin, ensure that you have:
An Elastic Compute Service (ECS) instance running Alibaba Cloud Linux 3, kernel version
5.10.134-14or latersudoaccess on the instance
Enable and configure the feature
Connect to the ECS instance. For instructions, see Use Workbench to log on to a Linux instance.
Enable Page Cache Limit globally.
sudo sh -c 'echo 1 > /sys/kernel/mm/pagecache_limit/enabled'Create a memcg directory. This example uses
/sys/fs/cgroup/memory/test/.sudo mkdir -p /sys/fs/cgroup/memory/test/Set the page cache limit to 10 MiB (10,485,760 bytes).
sudo sh -c 'echo 10485760 > /sys/fs/cgroup/memory/test/memory.pagecache_limit.size'Configure the reclaim mode. Choose one of the following options based on your workload:
Asynchronous reclaim:
sudo sh -c 'echo 0 > /sys/fs/cgroup/memory/test/memory.pagecache_limit.sync'Synchronous reclaim:
sudo sh -c 'echo 1 > /sys/fs/cgroup/memory/test/memory.pagecache_limit.sync'
Enable Page Cache Limit for the memcg.
sudo sh -c 'echo 1 > /sys/fs/cgroup/memory/test/memory.pagecache_limit.enable'
Create a test page cache
Install the
libcgrouppackage, which provides thecgexeccommand.sudo yum install libcgroup-toolsCreate a 20 MiB test file and read it under the
testmemcg to generate 20 MiB of page cache.sudo dd if=/dev/zero of=./testfile bs=1M count=20 oflag=direct sudo cgexec -g "memory:test" cat ./testfile > /dev/null
Verify the results
Check page cache usage. The
cachefield inmemory.statshows the total page cache consumed by the memcg.grep cache /sys/fs/cgroup/memory/test/memory.statThe output should show
cacheat approximately 10,543,104 bytes (~10 MiB), confirming that page cache usage is capped at the configured limit.
Check how much page cache was reclaimed. The
pagecache_limit_reclaimed_kbfield inmemory.exstatshows the cumulative kilobytes of page cache reclaimed by the feature.cat /sys/fs/cgroup/memory/test/memory.exstatThe output should show
pagecache_limit_reclaimed_kbat approximately 10,108 KB (~10 MiB), confirming that 10 MiB of excess page cache was reclaimed.
Result: A 20 MiB page cache was created. Page Cache Limit capped usage at 10 MiB and reclaimed the remaining 10 MiB as expected.
Note: Ifpagecache_limit_reclaimed_kbis higher than expected, excessive sequential read-ahead may be the cause. Reduce the read-ahead size for the disk device and then retest:Replaceecho 128 | sudo tee /sys/block/<disk-device>/queue/read_ahead_kb<disk-device>with your disk device name (for example,vda). Theread_ahead_kbparameter controls how many kilobytes the kernel prefetches during sequential reads. Lowering it reduces unnecessary page cache allocation.
What's next
Memcg backend asynchronous reclaim — Learn about the complementary feature that handles typical memory pressure without blocking processes.