요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
===============================
Documentation for /proc/sys/vm/
===============================
kernel version 2.6.29
Copyright (c) 1998, 1999, Rik van Riel <riel@nl.linux.org>
Copyright (c) 2008 Peter W. Morreale <pmorreale@novell.com>
For general info and legal blurb, please look in index.rst.
------------------------------------------------------------------------------
This file contains the documentation for the sysctl files in
/proc/sys/vm and is valid for Linux kernel version 2.6.29.
The files in this directory can be used to tune the operation
of the virtual memory (VM) subsystem of the Linux kernel and
the writeout of dirty data to disk.
Default values and initialization routines for most of these
files can be found in mm/swap.c.
Currently, these files are in /proc/sys/vm:
- admin_reserve_kbytes
- compact_memory
- compaction_proactiveness
- compact_unevictable_allowed
- defrag_mode
- dirty_background_bytes
- dirty_background_ratio
- dirty_bytes
- dirty_expire_centisecs
- dirty_ratio
- dirtytime_expire_seconds
- dirty_writeback_centisecs
- drop_caches
- enable_soft_offline
- extfrag_threshold
- highmem_is_dirtyable
- hugetlb_shm_group
- laptop_mode
- legacy_va_layout
- lowmem_reserve_ratio
- max_map_count
- mem_profiling (only if CONFIG_MEM_ALLOC_PROFILING=y)
- memory_failure_early_kill
- memory_failure_recovery
- min_free_kbytes
- min_slab_ratio
- min_unmapped_ratio
- mmap_min_addr
- mmap_rnd_bits
- mmap_rnd_compat_bits
- nr_hugepages
- nr_hugepages_mempolicy
- nr_overcommit_hugepages
- nr_trim_pages (only if CONFIG_MMU=n)
- numa_zonelist_order
- oom_dump_tasks
- oom_kill_allocating_task
- overcommit_kbytes
- overcommit_memory
- overcommit_ratio
- page-cluster
- page_lock_unfairness
- panic_on_oom
- percpu_pagelist_high_fraction
- stat_interval
- stat_refresh
- numa_stat
- swappiness
- unprivileged_userfaultfd
- user_reserve_kbytes
- vfs_cache_pressure
- vfs_cache_pressure_denom
- watermark_boost_factor
- watermark_scale_factor
- zone_reclaim_mode
admin_reserve_kbytes
====================
The amount of free memory in the system that should be reserved for users
with the capability cap_sys_admin.
admin_reserve_kbytes defaults to min(3% of free pages, 8MB)
That should provide enough for the admin to log in and kill a process,
if necessary, under the default overcommit 'guess' mode.
Systems running under overcommit 'never' should increase this to account
for the full Virtual Memory Size of programs used to recover. Otherwise,
root may not be able to log in to recover the system.
How do you calculate a minimum useful reserve?
sshd or login + bash (or some other shell) + top (or ps, kill, etc.)
For overcommit 'guess', we can sum resident set sizes (RSS).
On x86_64 this is about 8MB.
For overcommit 'never', we can take the max of their virtual sizes (VSZ)
and add the sum of their RSS.
On x86_64 this is about 128MB.
Changing this takes effect whenever an application requests memory.
compact_memory
==============
Available only when CONFIG_COMPACTION is set. When 1 is written to the file,
all zones are compacted such that free memory is available in contiguous
blocks where possible. This can be important for example in the allocation of
huge pages although processes will also directly compact memory as required.
compaction_proactiveness
========================
This tunable takes a value in the range [0, 100] with a default value of
20. This tunable determines how aggressively compaction is done in the
background. Write of a non zero value to this tunable will immediately
trigger the proactive compaction. Setting it to 0 disables proactive compaction.
Note that compaction has a non-trivial system-wide impact as pages
belonging to different processes are moved around, which could also lead
to latency spikes in unsuspecting applications. The kernel employs
various heuristics to avoid wasting CPU cycles if it detects that
proactive compaction is not being effective.
Setting the value above 80 will, in addition to lowering the acceptable level
of fragmentation, make the compaction code more sensitive to increases in
fragmentation, i.e. compaction will trigger more often, but reduce
fragmentation by a smaller amount.
This makes the fragmentation level more stable over time.
Be careful when setting it to extreme values like 100, as that may
cause excessive background compaction activity.
compact_unevictable_allowed
===========================
Available only when CONFIG_COMPACTION is set. When set to 1, compaction is
allowed to examine the unevictable lru (mlocked pages) for pages to compact.
This should be used on systems where stalls for minor page faults are an
acceptable trade for large contiguous free memory. Set to 0 to prevent
compaction from moving pages that are unevictable. Default value is 1.
On CONFIG_PREEMPT_RT the default value is 0 in order to avoid a page fault, due
to compaction, which would block the task from becoming active until the fault
is resolved.
defrag_mode
===========
When set to 1, the page allocator tries harder to avoid fragmentation
and maintain the ability to produce huge pages / higher-order pages.
It is recommended to enable this right after boot, as fragmentation,
once it occurred, can be long-lasting or even permanent.
dirty_background_bytes
======================
Contains the amount of dirty memory at which the background kernel
flusher threads will start writeback.
Note:
dirty_background_bytes is the counterpart of dirty_background_ratio. Only
one of them may be specified at a time. When one sysctl is written it is
immediately taken into account to evaluate the dirty memory limits and the
other appears as 0 when read.
dirty_background_ratio
======================
Contains, as a percentage of total available memory that contains free pages
and reclaimable pages, the number of pages at which the background kernel
flusher threads will start writing out dirty data.
The total available memory is not equal to total system memory.
dirty_bytes
===========
Contains the amount of dirty memory at which a process generating disk writes
will itself start writeback.
Note: dirty_bytes is the counterpart of dirty_ratio. Only one of them may be
specified at a time. When one sysctl is written it is immediately taken into
account to evaluate the dirty memory limits and the other appears as 0 when
read.
Note: the minimum value allowed for dirty_bytes is two pages (in bytes); any
value lower than this limit will be ignored and the old configuration will be
retained.
dirty_expire_centisecs
======================
This tunable is used to define when dirty data is old enough to be eligible
for writeout by the kernel flusher threads. It is expressed in 100'ths
of a second. Data which has been dirty in-memory for longer than this
interval will be written out next time a flusher thread wakes up.
dirty_ratio
===========
Contains, as a percentage of total available memory that contains free pages
and reclaimable pages, the number of pages at which a process which is
generating disk writes will itself start writing out dirty data.
The total available memory is not equal to total system memory.
dirtytime_expire_seconds
========================
When a lazytime inode is constantly having its pages dirtied, the inode with
an updated timestamp will never get chance to be written out. And, if the
only thing that has happened on the file system is a dirtytime inode caused
by an atime update, a worker will be scheduled to make sure that inode
eventually gets pushed out to disk. This tunable is used to define when dirty
inode is old enough to be eligible for writeback by the kernel flusher threads.
And, it is also used as the interval to wakeup dirtytime_writeback thread.
dirty_writeback_centisecs
=========================
The kernel flusher threads will periodically wake up and write `old` data
out to disk. This tunable expresses the interval between those wakeups, in
100'ths of a second.
Setting this to zero disables periodic writeback altogether.
drop_caches
===========
Writing to this will cause the kernel to drop clean caches, as well as
reclaimable slab objects like dentries and inodes. Once dropped, their
memory becomes free.
To free pagecache::
echo 1 > /proc/sys/vm/drop_caches
To free reclaimable slab objects (includes dentries and inodes)::
echo 2 > /proc/sys/vm/drop_caches
To free slab objects and pagecache::
echo 3 > /proc/sys/vm/drop_caches
This is a non-destructive operation and will not free any dirty objects.
To increase the number of objects freed by this operation, the user may run
`sync` prior to writing to /proc/sys/vm/drop_caches. This will minimize the
number of dirty objects on the system and create more candidates to be
dropped.
This file is not a means to control the growth of the various kernel caches
(inodes, dentries, pagecache, etc...) These objects are automatically
reclaimed by the kernel when memory is needed elsewhere on the system.
Use of this file can cause performance problems. Since it discards cached
objects, it may cost a significant amount of I/O and CPU to recreate the
dropped objects, especially if they were under heavy use. Because of this,
use outside of a testing or debugging environment is not recommended.
You may see informational messages in your kernel log when this file is
used::
cat (1234): drop_caches: 3
These are informational only. They do not mean that anything is wrong
with your system. To disable them, echo 4 (bit 2) into drop_caches.
enable_soft_offline
===================
Correctable memory errors are very common on servers. Soft-offline is kernel's
solution for memory pages having (excessive) corrected memory errors.
For different types of page, soft-offline has different behaviors / costs.
- For a raw error page, soft-offline migrates the in-use page's content to
a new raw page.
- For a page that is part of a transparent hugepage, soft-offline splits the
transparent hugepage into raw pages, then migrates only the raw error page.
As a result, user is transparently backed by 1 less hugepage, impacting
memory access performance.
- For a page that is part of a HugeTLB hugepage, soft-offline first migrates
the entire HugeTLB hugepage, during which a free hugepage will be consumed
as migration target. Then the original hugepage is dissolved into raw
pages without compensation, reducing the capacity of the HugeTLB pool by 1.
It is user's call to choose between reliability (staying away from fragile
physical memory) vs performance / capacity implications in transparent and
HugeTLB cases.
For all architectures, enable_soft_offline controls whether to soft offline
memory pages. When set to 1, kernel attempts to soft offline the pages
whenever it thinks needed. When set to 0, kernel returns EOPNOTSUPP to
the request to soft offline the pages. Its default value is 1.
It is worth mentioning that after setting enable_soft_offline to 0, the
following requests to soft offline pages will not be performed:
- Request to soft offline pages from RAS Correctable Errors Collector.
- On ARM, the request to soft offline pages from GHES driver.
- On PARISC, the request to soft offline pages from Page Deallocation Table.
extfrag_threshold
=================
This parameter affects whether the kernel will compact memory or direct
reclaim to satisfy a high-order allocation. The extfrag/extfrag_index file in
debugfs shows what the fragmentation index for each order is in each zone in
the system. Values tending towards 0 imply allocations would fail due to lack
of memory, values towards 1000 imply failures are due to fragmentation and -1
implies that the allocation will succeed as long as watermarks are met.
The kernel will not compact memory in a zone if the
fragmentation index is <= extfrag_threshold. The default value is 500.
highmem_is_dirtyable
====================
Available only for systems with CONFIG_HIGHMEM enabled (32b systems).
This parameter controls whether the high memory is considered for dirty
writers throttling. This is not the case by default which means that
only the amount of memory directly visible/usable by the kernel can
be dirtied. As a result, on systems with a large amount of memory and
lowmem basically depleted writers might be throttled too early and
streaming writes can get very slow.
Changing the value to non zero would allow more memory to be dirtied
and thus allow writers to write more data which can be flushed to the
storage more effectively. Note this also comes with a risk of pre-mature
OOM killer because some writers (e.g. direct block device writes) can
only use the low memory and they can fill it up with dirty data without
any throttling.
hugetlb_shm_group
=================
hugetlb_shm_group contains group id that is allowed to create SysV
shared memory segment using hugetlb page.
laptop_mode
===========
laptop_mode is a knob that controls "laptop mode". All the things that are
controlled by this knob are discussed in Documentation/admin-guide/laptops/laptop-mode.rst.
legacy_va_layout
================
If non-zero, this sysctl disables the new 32-bit mmap layout - the kernel
will use the legacy (2.4) layout for all processes.
lowmem_reserve_ratio
====================
For some specialised workloads on highmem machines it is dangerous for
the kernel to allow process memory to be allocated from the "lowmem"
zone. This is because that memory could then be pinned via the mlock()
system call, or by unavailability of swapspace.
And on large highmem machines this lack of reclaimable lowmem memory
can be fatal.
So the Linux page allocator has a mechanism which prevents allocations
which *could* use highmem from using too much lowmem. This means that
a certain amount of lowmem is defended from the possibility of being
captured into pinned user memory.
(The same argument applies to the old 16 megabyte ISA DMA region. This
mechanism will also defend that region from allocations which could use
highmem or lowmem).
The `lowmem_reserve_ratio` tunable determines how aggressive the kernel is
in defending these lower zones.
If you have a machine which uses highmem or ISA DMA and your
applications are using mlock(), or if you are running with no swap then
you probably should change the lowmem_reserve_ratio setting.
The lowmem_reserve_ratio is an array. You can see them by reading this file::
% cat /proc/sys/vm/lowmem_reserve_ratio
256 256 32
But, these values are not used directly. The kernel calculates # of protection
pages for each zones from them. These are shown as array of protection pages
in /proc/zoneinfo like the following. (This is an example of x86-64 box).
Each zone has an array of protection pages like this::
Node 0, zone DMA
pages free 1355
min 3
low 3
high 4
:
:
numa_other 0
protection: (0, 2004, 2004, 2004)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
pagesets
cpu: 0 pcp: 0
:
These protections are added to score to judge whether this zone should be used
for page allocation or should be reclaimed.
In this example, if normal pages (index=2) are required to this DMA zone and
watermark[WMARK_HIGH] is used for watermark, the kernel judges this zone should
not be used because pages_free(1355) is smaller than watermark + protection[2]
(4 + 2004 = 2008). If this protection value is 0, this zone would be used for
normal page requirement. If requirement is DMA zone(index=0), protection[0]
(=0) is used.
zone[i]'s protection[j] is calculated by following expression::
(i < j):
zone[i]->protection[j]
= (total sums of managed_pages from zone[i+1] to zone[j] on the node)
/ lowmem_reserve_ratio[i];
(i = j):
(should not be protected. = 0;
(i > j):
(not necessary, but looks 0)
The default values of lowmem_reserve_ratio[i] are
=== ====================================
256 (if zone[i] means DMA or DMA32 zone)
32 (others)
=== ====================================
As above expression, they are reciprocal number of ratio.
256 means 1/256. # of protection pages becomes about "0.39%" of total managed
pages of higher zones on the node.
If you would like to protect more pages, smaller values are effective.
The minimum value is 1 (1/1 -> 100%). The value less than 1 completely
disables protection of the pages.
max_map_count
=============
This file contains the maximum number of memory map areas a process
may have. Memory map areas are used as a side-effect of calling
malloc, directly by mmap, mprotect, and madvise, and also when loading
shared libraries.
While most applications need less than a thousand maps, certain
programs, particularly malloc debuggers, may consume lots of them,
e.g., up to one or two maps per allocation.
The default value is 65530.
mem_profiling
==============
Enable memory profiling (when CONFIG_MEM_ALLOC_PROFILING=y)
1: Enable memory profiling.
0: Disable memory profiling.
Enabling memory profiling introduces a small performance overhead for all
memory allocations.
The default value depends on CONFIG_MEM_ALLOC_PROFILING_ENABLED_BY_DEFAULT.
memory_failure_early_kill
=========================
Control how to kill processes when uncorrected memory error (typically
a 2bit error in a memory module) is detected in the background by hardware
that cannot be handled by the kernel. In some cases (like the page
still having a valid copy on disk) the kernel will handle the failure
transparently without affecting any applications. But if there is
no other up-to-date copy of the data it will kill to prevent any data
corruptions from propagating.
1: Kill all processes that have the corrupted and not reloadable page mapped
as soon as the corruption is detected. Note this is not supported
for a few types of pages, like kernel internally allocated data or
the swap cache, but works for the majority of user pages.
0: Only unmap the corrupted page from all processes and only kill a process
who tries to access it.
The kill is done using a catchable SIGBUS with BUS_MCEERR_AO, so processes can
handle this if they want to.
This is only active on architectures/platforms with advanced machine
check handling and depends on the hardware capabilities.
Applications can override this setting individually with the PR_MCE_KILL prctl
memory_failure_recovery
=======================
Enable memory failure recovery (when supported by the platform)
1: Attempt recovery.
0: Always panic on a memory failure.
min_free_kbytes
===============
This is used to force the Linux VM to keep a minimum number
of kilobytes free. The VM uses this number to compute a
watermark[WMARK_MIN] value for each lowmem zone in the system.
Each lowmem zone gets a number of reserved free pages based
proportionally on its size.
Some minimal amount of memory is needed to satisfy PF_MEMALLOC
allocations; if you set this to lower than 1024KB, your system will
become subtly broken, and prone to deadlock under high loads.
Setting this too high will OOM your machine instantly.
min_slab_ratio
==============
This is available only on NUMA kernels.
A percentage of the total pages in each zone. On Zone reclaim
(fallback from the local zone occurs) slabs will be reclaimed if more
than this percentage of pages in a zone are reclaimable slab pages.
This insures that the slab growth stays under control even in NUMA
systems that rarely perform global reclaim.
The default is 5 percent.
Note that slab reclaim is triggered in a per zone / node fashion.
The process of reclaiming slab memory is currently not node specific
and may not be fast.
min_unmapped_ratio
==================
This is available only on NUMA kernels.
This is a percentage of the total pages in each zone. Zone reclaim will
only occur if more than this percentage of pages are in a state that
zone_reclaim_mode allows to be reclaimed.
If zone_reclaim_mode has the value 4 OR'd, then the percentage is compared
against all file-backed unmapped pages including swapcache pages and tmpfs
files. Otherwise, only unmapped pages backed by normal files but not tmpfs
files and similar are considered.
The default is 1 percent.
mmap_min_addr
=============
This file indicates the amount of address space which a user process will
be restricted from mmapping. Since kernel null dereference bugs could
accidentally operate based on the information in the first couple of pages
of memory userspace processes should not be allowed to write to them. By
default this value is set to 0 and no protections will be enforced by the
security module. Setting this value to something like 64k will allow the
vast majority of applications to work correctly and provide defense in depth
against future potential kernel bugs.
mmap_rnd_bits
=============
This value can be used to select the number of bits to use to
determine the random offset to the base address of vma regions
resulting from mmap allocations on architectures which support
tuning address space randomization. This value will be bounded
by the architecture's minimum and maximum supported values.
This value can be changed after boot using the
/proc/sys/vm/mmap_rnd_bits tunable
mmap_rnd_compat_bits
====================
This value can be used to select the number of bits to use to
determine the random offset to the base address of vma regions
resulting from mmap allocations for applications run in
compatibility mode on architectures which support tuning address
space randomization. This value will be bounded by the
architecture's minimum and maximum supported values.
This value can be changed after boot using the
/proc/sys/vm/mmap_rnd_compat_bits tunable
nr_hugepages
============
Change the minimum size of the hugepage pool.
See Documentation/admin-guide/mm/hugetlbpage.rst
hugetlb_optimize_vmemmap
========================
This knob is not available when the size of 'struct page' (a structure defined
in include/linux/mm_types.h) is not power of two (an unusual system config could
result in this).
Enable (set to 1) or disable (set to 0) HugeTLB Vmemmap Optimization (HVO).
Once enabled, the vmemmap pages of subsequent allocation of HugeTLB pages from
buddy allocator will be optimized (7 pages per 2MB HugeTLB page and 4095 pages
per 1GB HugeTLB page), whereas already allocated HugeTLB pages will not be
optimized. When those optimized HugeTLB pages are freed from the HugeTLB pool
to the buddy allocator, the vmemmap pages representing that range needs to be
remapped again and the vmemmap pages discarded earlier need to be rellocated
again. If your use case is that HugeTLB pages are allocated 'on the fly' (e.g.
never explicitly allocating HugeTLB pages with 'nr_hugepages' but only set
'nr_overcommit_hugepages', those overcommitted HugeTLB pages are allocated 'on
the fly') instead of being pulled from the HugeTLB pool, you should weigh the
benefits of memory savings against the more overhead (~2x slower than before)
of allocation or freeing HugeTLB pages between the HugeTLB pool and the buddy
allocator. Another behavior to note is that if the system is under heavy memory
pressure, it could prevent the user from freeing HugeTLB pages from the HugeTLB
pool to the buddy allocator since the allocation of vmemmap pages could be
failed, you have to retry later if your system encounter this situation.
Once disabled, the vmemmap pages of subsequent allocation of HugeTLB pages from
buddy allocator will not be optimized meaning the extra overhead at allocation
time from buddy allocator disappears, whereas already optimized HugeTLB pages
will not be affected. If you want to make sure there are no optimized HugeTLB
pages, you can set "nr_hugepages" to 0 first and then disable this. Note that
writing 0 to nr_hugepages will make any "in use" HugeTLB pages become surplus
pages. So, those surplus pages are still optimized until they are no longer
in use. You would need to wait for those surplus pages to be released before
there are no optimized pages in the system.
nr_hugepages_mempolicy
======================
Change the size of the hugepage pool at run-time on a specific
set of NUMA nodes.
See Documentation/admin-guide/mm/hugetlbpage.rst
nr_overcommit_hugepages
=======================
Change the maximum size of the hugepage pool. The maximum is
nr_hugepages + nr_overcommit_hugepages.
See Documentation/admin-guide/mm/hugetlbpage.rst
nr_trim_pages
=============
This is available only on NOMMU kernels.
This value adjusts the excess page trimming behaviour of power-of-2 aligned
NOMMU mmap allocations.
A value of 0 disables trimming of allocations entirely, while a value of 1
trims excess pages aggressively. Any value >= 1 acts as the watermark where
trimming of allocations is initiated.
The default value is 1.
See Documentation/admin-guide/mm/nommu-mmap.rst for more information.
numa_zonelist_order
===================
This sysctl is only for NUMA and it is deprecated. Anything but
Node order will fail!
'where the memory is allocated from' is controlled by zonelists.
(This documentation ignores ZONE_HIGHMEM/ZONE_DMA32 for simple explanation.
you may be able to read ZONE_DMA as ZONE_DMA32...)
In non-NUMA case, a zonelist for GFP_KERNEL is ordered as following.
ZONE_NORMAL -> ZONE_DMA
This means that a memory allocation request for GFP_KERNEL will
get memory from ZONE_DMA only when ZONE_NORMAL is not available.
In NUMA case, you can think of following 2 types of order.
Assume 2 node NUMA and below is zonelist of Node(0)'s GFP_KERNEL::
(A) Node(0) ZONE_NORMAL -> Node(0) ZONE_DMA -> Node(1) ZONE_NORMAL
(B) Node(0) ZONE_NORMAL -> Node(1) ZONE_NORMAL -> Node(0) ZONE_DMA.
Type(A) offers the best locality for processes on Node(0), but ZONE_DMA
will be used before ZONE_NORMAL exhaustion. This increases possibility of
out-of-memory(OOM) of ZONE_DMA because ZONE_DMA is tend to be small.
Type(B) cannot offer the best locality but is more robust against OOM of
the DMA zone.
Type(A) is called as "Node" order. Type (B) is "Zone" order.
"Node order" orders the zonelists by node, then by zone within each node.
Specify "[Nn]ode" for node order
"Zone Order" orders the zonelists by zone type, then by node within each
zone. Specify "[Zz]one" for zone order.
Specify "[Dd]efault" to request automatic configuration.
On 32-bit, the Normal zone needs to be preserved for allocations accessible
by the kernel, so "zone" order will be selected.
On 64-bit, devices that require DMA32/DMA are relatively rare, so "node"
order will be selected.
Default order is recommended unless this is causing problems for your
system/application.
oom_dump_tasks
==============
Enables a system-wide task dump (excluding kernel threads) to be produced
when the kernel performs an OOM-killing and includes such information as
pid, uid, tgid, vm size, rss, pgtables_bytes, swapents, oom_score_adj
score, and name. This is helpful to determine why the OOM killer was
invoked, to identify the rogue task that caused it, and to determine why
the OOM killer chose the task it did to kill.
If this is set to zero, this information is suppressed. On very
large systems with thousands of tasks it may not be feasible to dump
the memory state information for each one. Such systems should not
be forced to incur a performance penalty in OOM conditions when the
information may not be desired.
If this is set to non-zero, this information is shown whenever the
OOM killer actually kills a memory-hogging task.
The default value is 1 (enabled).
oom_kill_allocating_task
========================
This enables or disables killing the OOM-triggering task in
out-of-memory situations.
If this is set to zero, the OOM killer will scan through the entire
tasklist and select a task based on heuristics to kill. This normally
selects a rogue memory-hogging task that frees up a large amount of
memory when killed.
If this is set to non-zero, the OOM killer simply kills the task that
triggered the out-of-memory condition. This avoids the expensive
tasklist scan.
If panic_on_oom is selected, it takes precedence over whatever value
is used in oom_kill_allocating_task.
The default value is 0.
overcommit_kbytes
=================
When overcommit_memory is set to 2, the committed address space is not
permitted to exceed swap plus this amount of physical RAM. See below.
Note: overcommit_kbytes is the counterpart of overcommit_ratio. Only one
of them may be specified at a time. Setting one disables the other (which
then appears as 0 when read).
overcommit_memory
=================
This value contains a flag that enables memory overcommitment.
When this flag is 0, the kernel compares the userspace memory request
size against total memory plus swap and rejects obvious overcommits.
When this flag is 1, the kernel pretends there is always enough
memory until it actually runs out.
When this flag is 2, the kernel uses a "never overcommit"
policy that attempts to prevent any overcommit of memory.
Note that user_reserve_kbytes affects this policy.
This feature can be very useful because there are a lot of
programs that malloc() huge amounts of memory "just-in-case"
and don't use much of it.
The default value is 0.
See Documentation/mm/overcommit-accounting.rst and
mm/util.c::__vm_enough_memory() for more information.
overcommit_ratio
================
When overcommit_memory is set to 2, the committed address
space is not permitted to exceed swap plus this percentage
of physical RAM. See above.
page-cluster
============
page-cluster controls the number of pages up to which consecutive pages
are read in from swap in a single attempt. This is the swap counterpart
to page cache readahead.
The mentioned consecutivity is not in terms of virtual/physical addresses,
but consecutive on swap space - that means they were swapped out together.
It is a logarithmic value - setting it to zero means "1 page", setting
it to 1 means "2 pages", setting it to 2 means "4 pages", etc.
Zero disables swap readahead completely.
The default value is three (eight pages at a time). There may be some
small benefits in tuning this to a different value if your workload is
swap-intensive.
Lower values mean lower latencies for initial faults, but at the same time
extra faults and I/O delays for following faults if they would have been part of
that consecutive pages readahead would have brought in.
page_lock_unfairness
====================
This value determines the number of times that the page lock can be
stolen from under a waiter. After the lock is stolen the number of times
specified in this file (default is 5), the "fair lock handoff" semantics
will apply, and the waiter will only be awakened if the lock can be taken.
panic_on_oom
============
This enables or disables panic on out-of-memory feature.
If this is set to 0, the kernel will kill some rogue process,
called oom_killer. Usually, oom_killer can kill rogue processes and
system will survive.
If this is set to 1, the kernel panics when out-of-memory happens.
However, if a process limits using nodes by mempolicy/cpusets,
and those nodes become memory exhaustion status, one process
may be killed by oom-killer. No panic occurs in this case.
Because other nodes' memory may be free. This means system total status
may be not fatal yet.
If this is set to 2, the kernel panics compulsorily even on the
above-mentioned. Even oom happens under memory cgroup, the whole
system panics.
The default value is 0.
1 and 2 are for failover of clustering. Please select either
according to your policy of failover.
panic_on_oom=2+kdump gives you very strong tool to investigate
why oom happens. You can get snapshot.
percpu_pagelist_high_fraction
=============================
This is the fraction of pages in each zone that are can be stored to
per-cpu page lists. It is an upper boundary that is divided depending
on the number of online CPUs. The min value for this is 8 which means
that we do not allow more than 1/8th of pages in each zone to be stored
on per-cpu page lists. This entry only changes the value of hot per-cpu
page lists. A user can specify a number like 100 to allocate 1/100th of
each zone between per-cpu lists.
The batch value of each per-cpu page list remains the same regardless of
the value of the high fraction so allocation latencies are unaffected.
The initial value is zero. Kernel uses this value to set the high pcp->high
mark based on the low watermark for the zone and the number of local
online CPUs. If the user writes '0' to this sysctl, it will revert to
this default behavior.
stat_interval
=============
The time interval between which vm statistics are updated. The default
is 1 second.
stat_refresh
============
Any read or write (by root only) flushes all the per-cpu vm statistics
into their global totals, for more accurate reports when testing
e.g. cat /proc/sys/vm/stat_refresh /proc/meminfo
As a side-effect, it also checks for negative totals (elsewhere reported
as 0) and "fails" with EINVAL if any are found, with a warning in dmesg.
(At time of writing, a few stats are known sometimes to be found negative,
with no ill effects: errors and warnings on these stats are suppressed.)
numa_stat
=========
This interface allows runtime configuration of numa statistics.
When page allocation performance becomes a bottleneck and you can tolerate
some possible tool breakage and decreased numa counter precision, you can
do::
echo 0 > /proc/sys/vm/numa_stat
When page allocation performance is not a bottleneck and you want all
tooling to work, you can do::
echo 1 > /proc/sys/vm/numa_stat
swappiness
==========
This control is used to define the rough relative IO cost of swapping
and filesystem paging, as a value between 0 and 200. At 100, the VM
assumes equal IO cost and will thus apply memory pressure to the page
cache and swap-backed pages equally; lower values signify more
expensive swap IO, higher values indicates cheaper.
Keep in mind that filesystem IO patterns under memory pressure tend to
be more efficient than swap's random IO. An optimal value will require
experimentation and will also be workload-dependent.
The default value is 60.
For in-memory swap, like zram or zswap, as well as hybrid setups that
have swap on faster devices than the filesystem, values beyond 100 can
be considered. For example, if the random IO against the swap device
is on average 2x faster than IO from the filesystem, swappiness should
be 133 (x + 2x = 200, 2x = 133.33).
At 0, the kernel will not initiate swap until the amount of free and
file-backed pages is less than the high watermark in a zone.
unprivileged_userfaultfd
========================
This flag controls the mode in which unprivileged users can use the
userfaultfd system calls. Set this to 0 to restrict unprivileged users
to handle page faults in user mode only. In this case, users without
SYS_CAP_PTRACE must pass UFFD_USER_MODE_ONLY in order for userfaultfd to
succeed. Prohibiting use of userfaultfd for handling faults from kernel
mode may make certain vulnerabilities more difficult to exploit.
Set this to 1 to allow unprivileged users to use the userfaultfd system
calls without any restrictions.
The default value is 0.
Another way to control permissions for userfaultfd is to use
/dev/userfaultfd instead of userfaultfd(2). See
Documentation/admin-guide/mm/userfaultfd.rst.
user_reserve_kbytes
===================
When overcommit_memory is set to 2, "never overcommit" mode, reserve
min(3% of current process size, user_reserve_kbytes) of free memory.
This is intended to prevent a user from starting a single memory hogging
process, such that they cannot recover (kill the hog).
user_reserve_kbytes defaults to min(3% of the current process size, 128MB).
If this is reduced to zero, then the user will be allowed to allocate
all free memory with a single process, minus admin_reserve_kbytes.
Any subsequent attempts to execute a command will result in
"fork: Cannot allocate memory".
Changing this takes effect whenever an application requests memory.
vfs_cache_pressure
==================
This percentage value controls the tendency of the kernel to reclaim
the memory which is used for caching of directory and inode objects.
At the default value of vfs_cache_pressure=vfs_cache_pressure_denom the kernel
will attempt to reclaim dentries and inodes at a "fair" rate with respect to
pagecache and swapcache reclaim. Decreasing vfs_cache_pressure causes the
kernel to prefer to retain dentry and inode caches. When vfs_cache_pressure=0,
the kernel will never reclaim dentries and inodes due to memory pressure and
this can easily lead to out-of-memory conditions. Increasing vfs_cache_pressure
beyond vfs_cache_pressure_denom causes the kernel to prefer to reclaim dentries
and inodes.
Increasing vfs_cache_pressure significantly beyond vfs_cache_pressure_denom may
have negative performance impact. Reclaim code needs to take various locks to
find freeable directory and inode objects. When vfs_cache_pressure equals
(10 * vfs_cache_pressure_denom), it will look for ten times more freeable
objects than there are.
Note: This setting should always be used together with vfs_cache_pressure_denom.
vfs_cache_pressure_denom
========================
Defaults to 100 (minimum allowed value). Requires corresponding
vfs_cache_pressure setting to take effect.
watermark_boost_factor
======================
This factor controls the level of reclaim when memory is being fragmented.
It defines the percentage of the high watermark of a zone that will be
reclaimed if pages of different mobility are being mixed within pageblocks.
The intent is that compaction has less work to do in the future and to
increase the success rate of future high-order allocations such as SLUB
allocations, THP and hugetlbfs pages.
To make it sensible with respect to the watermark_scale_factor
parameter, the unit is in fractions of 10,000. The default value of
15,000 means that up to 150% of the high watermark will be reclaimed in the
event of a pageblock being mixed due to fragmentation. The level of reclaim
is determined by the number of fragmentation events that occurred in the
recent past. If this value is smaller than a pageblock then a pageblocks
worth of pages will be reclaimed (e.g. 2MB on 64-bit x86). A boost factor
of 0 will disable the feature.
watermark_scale_factor
======================
This factor controls the aggressiveness of kswapd. It defines the
amount of memory left in a node/system before kswapd is woken up and
how much memory needs to be free before kswapd goes back to sleep.
The unit is in fractions of 10,000. The default value of 10 means the
distances between watermarks are 0.1% of the available memory in the
node/system. The maximum value is 3000, or 30% of memory.
A high rate of threads entering direct reclaim (allocstall) or kswapd
going to sleep prematurely (kswapd_low_wmark_hit_quickly) can indicate
that the number of free pages kswapd maintains for latency reasons is
too small for the allocation bursts occurring in the system. This knob
can then be used to tune kswapd aggressiveness accordingly.
zone_reclaim_mode
=================
Zone_reclaim_mode allows someone to set more or less aggressive approaches to
reclaim memory when a zone runs out of memory. If it is set to zero then no
zone reclaim occurs. Allocations will be satisfied from other zones / nodes
in the system.
This is value OR'ed together of
= ===================================
1 Zone reclaim on
2 Zone reclaim writes dirty pages out
4 Zone reclaim swaps pages
= ===================================
zone_reclaim_mode is disabled by default. For file servers or workloads
that benefit from having their data cached, zone_reclaim_mode should be
left disabled as the caching effect is likely to be more important than
data locality.
Consider enabling one or more zone_reclaim mode bits if it's known that the
workload is partitioned such that each partition fits within a NUMA node
and that accessing remote memory would cause a measurable performance
reduction. The page allocator will take additional actions before
allocating off node pages.
Allowing zone reclaim to write out pages stops processes that are
writing large amounts of data from dirtying pages on other nodes. Zone
reclaim will write out dirty pages if a zone fills up and so effectively
throttle the process. This may decrease the performance of a single process
since it cannot use all of system memory to buffer the outgoing writes
anymore but it preserve the memory on other nodes so that the performance
of other processes running on other nodes will not be affected.
Allowing regular swap effectively restricts allocations to the local
node unless explicitly overridden by memory policies or cpuset
configurations.
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
문서 범위와 VM sysctl 목록
1-83이 문서는 Rik van Riel과 Peter W. Morreale이 작성한 `/proc/sys/vm` sysctl 설명서이며 원문은 Linux kernel version 2.6.29를 기준으로 합니다. 일반 정보와 법적 안내는 `index.rst`를 참조하십시오.
이 디렉터리의 파일은 Linux kernel virtual memory(VM) subsystem의 동작과 dirty data의 disk writeout을 조정합니다. 대부분 항목의 기본값과 초기화 routine은 `mm/swap.c`에서 찾을 수 있습니다.
| 영역 | 주요 항목 |
|---|---|
| 회수·압축 | `compact_memory`, `compaction_proactiveness`, `drop_caches`, `zone_reclaim_mode` |
| dirty writeback | `dirty_background_*`, `dirty_*`, `dirtytime_expire_seconds` |
| OOM·overcommit | `panic_on_oom`, `oom_*`, `overcommit_*`, `*_reserve_kbytes` |
| HugeTLB·NUMA | `nr_hugepages*`, `hugetlb_*`, `numa_*`, `lowmem_reserve_ratio` |
| cache·watermark | `vfs_cache_pressure*`, `watermark_*`, `min_free_kbytes` |
admin_reserve_kbytes
84-112`cap_sys_admin` capability를 가진 사용자를 위해 시스템에 남겨 둘 free memory 양입니다. 기본값은 `min(free page의 3%, 8MB)`이며, 기본 overcommit `guess` mode에서 관리자가 login해 문제 process를 종료할 정도의 여유를 목표로 합니다.
overcommit `never` mode에서는 복구에 사용할 program의 전체 Virtual Memory Size까지 고려해 값을 늘려야 합니다. 그러지 않으면 root도 login하지 못할 수 있습니다.
유용한 최솟값은 `sshd` 또는 `login`, `bash` 같은 shell, `top` 또는 `ps`, `kill` 등의 복구 도구를 기준으로 계산합니다. `guess`에서는 RSS 합계를 사용하며 x86_64에서 약 8MB입니다. `never`에서는 최대 VSZ에 RSS 합계를 더하며 x86_64에서 약 128MB입니다. 변경은 application이 memory를 요청할 때마다 적용됩니다.
compact_memory
113-120`CONFIG_COMPACTION`이 설정된 경우에만 제공됩니다. 파일에 `1`을 쓰면 가능한 한 연속된 block으로 free memory가 생기도록 모든 zone을 compact합니다. process도 필요할 때 직접 compaction하지만 huge page allocation 등에 중요할 수 있습니다.
compaction_proactiveness
121-143background compaction의 적극성을 `[0, 100]` 범위로 지정하며 기본값은 `20`입니다. 0이 아닌 값을 쓰면 proactive compaction이 즉시 시작되고, `0`은 이를 비활성화합니다.
서로 다른 process의 page를 옮기므로 compaction은 시스템 전체에 무시하기 어려운 영향을 주고 예상하지 못한 application의 latency spike를 만들 수 있습니다. kernel은 proactive compaction이 효과적이지 않다고 판단하면 CPU cycle 낭비를 피하는 여러 heuristic을 사용합니다.
`80`보다 크게 설정하면 허용 가능한 fragmentation 수준이 낮아질 뿐 아니라 증가에도 더 민감해집니다. compaction은 더 자주 실행하되 한 번에 줄이는 fragmentation은 작아져 시간에 따른 수준이 안정될 수 있습니다. `100` 같은 극단값은 과도한 background compaction을 일으킬 수 있으므로 주의해야 합니다.
compact_unevictable_allowed
144-155`CONFIG_COMPACTION`이 설정된 경우에만 제공됩니다. `1`이면 compaction이 unevictable LRU의 `mlocked` page도 조사할 수 있습니다. 큰 연속 free memory를 얻는 대신 minor page fault stall을 감수할 수 있는 시스템에 적합합니다.
`0`은 unevictable page 이동을 막습니다. 일반 기본값은 `1`이지만 `CONFIG_PREEMPT_RT`에서는 compaction 때문에 생긴 page fault가 해소될 때까지 task가 active 상태가 되지 못하는 일을 피하려고 기본값이 `0`입니다.
defrag_mode
156-164`1`이면 page allocator가 fragmentation을 더 적극적으로 피하고 huge page 또는 higher-order page를 만들 수 있는 상태를 유지합니다. 이미 생긴 fragmentation은 오래 지속되거나 영구적일 수 있으므로 boot 직후 활성화하는 것이 권장됩니다.
dirty_background_bytes
165-177background kernel flusher thread가 writeback을 시작할 dirty memory 양을 byte로 지정합니다. `dirty_background_ratio`와 짝을 이루며 둘 중 하나만 지정할 수 있습니다. 한 sysctl에 쓰면 dirty limit 평가에 즉시 반영되고 다른 항목은 읽을 때 `0`으로 보입니다.
dirty_background_ratio
178-187background kernel flusher thread가 dirty data writeout을 시작할 page 수를 전체 available memory의 백분율로 지정합니다. 여기서 available memory는 free page와 reclaimable page를 포함하며 전체 system memory와 같지 않습니다.
dirty_bytes
188-203disk write를 생성하는 process가 직접 writeback을 시작할 dirty memory 양입니다. `dirty_ratio`와 짝을 이루며 둘 중 하나만 지정할 수 있습니다. 하나를 쓰면 즉시 반영되고 다른 값은 `0`으로 읽힙니다.
허용되는 최솟값은 byte 단위로 page 두 개입니다. 이보다 작은 값은 무시되고 기존 설정이 유지됩니다.
dirty_expire_centisecs
204-212dirty data가 kernel flusher thread의 writeout 대상이 될 만큼 오래됐다고 판단하는 시간을 1/100초 단위로 정합니다. memory에서 이 간격보다 오래 dirty 상태였던 data는 다음 flusher wakeup 때 기록됩니다.
dirty_ratio
213-222disk write를 생성하는 process가 직접 dirty data를 기록하기 시작할 page 수를 전체 available memory의 백분율로 지정합니다. available memory는 free page와 reclaimable page를 포함하며 전체 system memory와 같지 않습니다.
dirtytime_expire_seconds
223-234lazytime inode의 page가 계속 dirty해지면 갱신된 timestamp를 가진 inode가 writeout될 기회를 얻지 못할 수 있습니다. filesystem에서 일어난 일이 atime 갱신으로 생긴 dirtytime inode뿐이어도 worker를 예약해 inode가 결국 disk로 나가게 합니다.
이 값은 dirty inode가 kernel flusher thread의 writeback 대상이 될 만큼 오래됐다고 판단하는 시간이며, `dirtytime_writeback` thread를 깨우는 간격으로도 사용됩니다.
dirty_writeback_centisecs
235-244kernel flusher thread가 주기적으로 깨어나 `old` data를 disk에 쓰는 간격이며 단위는 1/100초입니다. `0`으로 설정하면 periodic writeback을 완전히 비활성화합니다.
drop_caches
245-286이 파일에 쓰면 kernel이 clean cache와 dentry·inode 같은 reclaimable slab object를 버립니다. 버린 memory는 free 상태가 됩니다.
pagecache만 비우려면 다음과 같이 실행합니다.
echo 1 > /proc/sys/vm/drop_caches
dentry와 inode를 포함한 reclaimable slab object만 비우려면 다음과 같이 실행합니다.
echo 2 > /proc/sys/vm/drop_caches
slab object와 pagecache를 함께 비우려면 다음과 같이 실행합니다.
echo 3 > /proc/sys/vm/drop_caches
이 작업은 destructive하지 않으며 dirty object는 해제하지 않습니다. 먼저 `sync`를 실행하면 dirty object 수가 줄어 더 많은 object가 drop 후보가 됩니다.
이 파일은 inode, dentry, pagecache 등 kernel cache의 증가를 제어하는 수단이 아닙니다. kernel은 다른 곳에 memory가 필요할 때 이를 자동 회수합니다. cache를 다시 만드는 데 많은 I/O와 CPU가 들 수 있으므로 testing 또는 debugging 환경 밖에서는 사용을 권장하지 않습니다.
사용할 때 kernel log에 다음과 같은 정보 메시지가 보일 수 있습니다.
cat (1234): drop_caches: 3
오류 메시지가 아닙니다. 표시를 끄려면 `drop_caches`에 `4`(bit 2)를 쓰십시오.
enable_soft_offline
287-324server에서 흔한 corrected memory error가 과도하게 발생한 page를 처리하는 kernel 기능이 soft-offline입니다. page 유형마다 동작과 비용이 다릅니다.
| page 유형 | soft-offline 동작과 비용 |
|---|---|
| raw error page | 사용 중인 page의 내용을 새 raw page로 migrate |
| transparent hugepage 일부 | hugepage를 raw page로 split한 뒤 error page만 migrate. 사용자는 hugepage 하나가 줄어 memory access 성능에 영향 |
| HugeTLB hugepage 일부 | 전체 HugeTLB hugepage를 migrate해 free hugepage 하나를 target으로 소비한 뒤 원본을 보상 없이 raw page로 dissolve. HugeTLB pool capacity가 1 감소 |
fragile physical memory를 피하는 reliability와 transparent hugepage·HugeTLB의 성능 및 capacity 비용 사이의 선택은 사용자 몫입니다.
모든 architecture에서 `1`이면 kernel이 필요하다고 판단할 때 page를 soft offline하려 시도하고, `0`이면 요청에 `EOPNOTSUPP`를 반환합니다. 기본값은 `1`입니다.
`0`으로 바꾸면 RAS Correctable Errors Collector의 요청, ARM의 GHES driver 요청, PARISC의 Page Deallocation Table 요청도 실행되지 않습니다.
extfrag_threshold
325-338higher-order allocation을 만족시키기 위해 kernel이 memory compaction과 direct reclaim 중 무엇을 할지에 영향을 줍니다. debugfs의 `extfrag/extfrag_index`는 zone별·order별 fragmentation index를 보여 줍니다.
`0`에 가까우면 memory 부족 때문에 allocation이 실패할 가능성이 크고, `1000`에 가까우면 fragmentation이 원인이며, `-1`은 watermark만 충족하면 성공함을 뜻합니다. fragmentation index가 `extfrag_threshold` 이하인 zone에서는 compact하지 않으며 기본값은 `500`입니다.
highmem_is_dirtyable
339-358`CONFIG_HIGHMEM`이 활성화된 32-bit system에서만 제공됩니다. high memory를 dirty writer throttling 계산에 포함할지 정합니다. 기본값에서는 kernel이 직접 보고 사용할 수 있는 memory만 dirty해질 수 있습니다.
memory가 크고 lowmem이 거의 고갈된 시스템에서는 writer가 너무 일찍 throttle되어 streaming write가 느려질 수 있습니다. 0이 아닌 값은 더 많은 memory를 dirty하게 해 storage로 더 효율적으로 flush할 수 있게 합니다.
반면 direct block device write처럼 low memory만 사용할 수 있는 writer가 throttling 없이 lowmem을 dirty data로 채워 premature OOM killer를 일으킬 위험이 있습니다.
hugetlb_shm_group
359-365hugetlb page를 사용하는 SysV shared memory segment를 만들 수 있도록 허용할 group id를 지정합니다.
laptop_mode
366-372`laptop_mode`는 laptop mode를 제어하는 knob입니다. 이 값이 제어하는 모든 항목은 `Documentation/admin-guide/laptops/laptop-mode.rst`에 설명되어 있습니다.
legacy_va_layout
373-3790이 아니면 새 32-bit mmap layout을 비활성화하고 모든 process에 legacy Linux 2.4 layout을 사용합니다.
lowmem_reserve_ratio
380-467highmem system의 일부 특수 workload에서는 process memory가 `lowmem` zone에서 할당되는 것이 위험합니다. 이 memory는 `mlock()`으로 pin되거나 swapspace가 없어 reclaim할 수 없게 될 수 있고, 큰 highmem machine에서는 reclaimable lowmem 부족이 치명적일 수 있습니다.
Linux page allocator는 highmem을 사용할 수 있는 allocation이 lowmem을 너무 많이 쓰지 못하게 하여 일정량을 pinned user memory로 빼앗기지 않도록 보호합니다. 같은 논리로 오래된 16MB ISA DMA region도 highmem이나 lowmem을 사용할 수 있는 allocation에서 보호합니다.
`lowmem_reserve_ratio`는 kernel이 lower zone을 얼마나 적극적으로 방어할지 정합니다. highmem 또는 ISA DMA를 쓰면서 application이 `mlock()`을 사용하거나 swap 없이 운영한다면 이 설정을 조정하는 것이 좋습니다.
값은 배열이며 다음 파일을 읽어 확인할 수 있습니다.
% cat /proc/sys/vm/lowmem_reserve_ratio
256 256 32
이 값은 직접 사용되지 않습니다. kernel은 각 zone의 protection page 수를 계산하고 `/proc/zoneinfo`의 protection 배열로 보여 줍니다. 다음은 x86-64 예입니다.
Node 0, zone DMA
pages free 1355
min 3
low 3
high 4
:
:
numa_other 0
protection: (0, 2004, 2004, 2004)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
pagesets
cpu: 0 pcp: 0
:
allocation에 zone을 사용할지 reclaim할지 판단할 때 protection을 watermark 점수에 더합니다. 예에서 normal page(index=2)를 DMA zone에서 요구하고 `watermark[WMARK_HIGH]`를 사용하면 `pages_free(1355)`가 `watermark + protection[2]`, 즉 `4 + 2004 = 2008`보다 작으므로 이 zone을 쓰지 않습니다. protection이 0이면 normal page 요청에 사용하며 DMA 요청(index=0)에는 `protection[0] (=0)`을 씁니다.
`zone[i]`의 `protection[j]`는 다음 식으로 계산합니다.
(i < j):
zone[i]->protection[j]
= (total sums of managed_pages from zone[i+1] to zone[j] on the node)
/ lowmem_reserve_ratio[i];
(i = j):
(should not be protected. = 0;
(i > j):
(not necessary, but looks 0)
| 기본값 | 적용 zone |
|---|---|
| `256` | `zone[i]`가 DMA 또는 DMA32 zone일 때 |
| `32` | 그 밖의 zone |
값은 ratio의 역수입니다. `256`은 `1/256`, 즉 node의 higher zone 전체 managed page 중 약 `0.39%`를 protection page로 만든다는 뜻입니다. 더 많이 보호하려면 더 작은 값을 사용합니다. 최솟값 `1`은 `1/1`, 즉 100%이며 1보다 작은 값은 page protection을 완전히 비활성화합니다.
max_map_count
468-482process 하나가 가질 수 있는 memory map area의 최대 개수입니다. VMA는 `malloc`, 직접 호출한 `mmap`, `mprotect`, `madvise`, shared library load의 결과로 만들어집니다.
대부분 application은 map 1,000개 미만이지만 malloc debugger 같은 일부 program은 allocation마다 한두 개까지 많은 map을 소비할 수 있습니다. 기본값은 `65530`입니다.
mem_profiling
483-497`CONFIG_MEM_ALLOC_PROFILING=y`일 때 memory profiling을 제어합니다. `1`은 활성화, `0`은 비활성화이며, 활성화하면 모든 memory allocation에 작은 performance overhead가 생깁니다.
기본값은 `CONFIG_MEM_ALLOC_PROFILING_ENABLED_BY_DEFAULT` 구성에 따라 결정됩니다.
memory_failure_early_kill
498-525hardware가 background에서 감지했지만 kernel이 처리할 수 없는 uncorrected memory error, 보통 memory module의 2-bit error가 발생했을 때 process를 어떻게 종료할지 정합니다. disk에 유효한 copy가 남은 page처럼 복구 가능한 경우에는 application에 영향 없이 투명하게 처리하지만, 최신 data의 다른 copy가 없으면 corruption 확산을 막기 위해 종료합니다.
| 값 | 동작 |
|---|---|
| `1` | corruption이 감지되는 즉시 손상되고 reload할 수 없는 page를 map한 모든 process를 종료. kernel 내부 할당 data나 swap cache 같은 일부 page 유형은 지원하지 않지만 대부분 user page에서 동작 |
| `0` | 모든 process에서 손상 page만 unmap하고 그 page에 접근하려는 process만 종료 |
종료는 catch 가능한 `SIGBUS`와 `BUS_MCEERR_AO`를 사용하므로 process가 원하면 처리할 수 있습니다. advanced machine check handling을 갖춘 architecture/platform에서만 활성화되고 hardware capability에 의존합니다. application은 `PR_MCE_KILL` `prctl`로 개별 override할 수 있습니다.
memory_failure_recovery
526-535platform이 지원할 때 memory failure recovery를 제어합니다. `1`은 복구를 시도하고 `0`은 memory failure가 발생하면 항상 panic합니다.
min_free_kbytes
536-551Linux VM이 최소한 free 상태로 유지해야 할 kilobyte 수입니다. VM은 이 값으로 system의 각 lowmem zone에 대한 `watermark[WMARK_MIN]`을 계산하고 zone 크기에 비례한 reserved free page를 둡니다.
`PF_MEMALLOC` allocation을 만족하려면 최소 memory가 필요합니다. `1024KB`보다 낮추면 system이 미묘하게 고장나고 부하가 높을 때 deadlock되기 쉬워집니다. 너무 높게 설정하면 machine이 즉시 OOM 상태가 됩니다.
min_slab_ratio
552-569NUMA kernel에서만 제공됩니다. 각 zone의 전체 page에 대한 백분율이며, local zone fallback이 일어나는 zone reclaim 때 reclaimable slab page가 이 비율보다 많으면 slab을 회수합니다.
global reclaim이 드문 NUMA system에서도 slab 증가를 제어하려는 설정이며 기본값은 `5%`입니다. slab reclaim trigger는 zone/node별이지만 실제 slab memory reclaim은 현재 node-specific하지 않고 빠르지 않을 수 있습니다.
min_unmapped_ratio
570-586NUMA kernel에서만 제공됩니다. 각 zone의 전체 page에 대한 백분율이며, `zone_reclaim_mode`가 회수하도록 허용한 상태의 page가 이 비율을 넘어야 zone reclaim이 실행됩니다.
`zone_reclaim_mode`에 값 `4`가 OR되어 있으면 swapcache page와 tmpfs file을 포함한 모든 file-backed unmapped page를 기준으로 비교합니다. 그렇지 않으면 tmpfs 같은 대상을 제외하고 일반 file이 backing하는 unmapped page만 고려합니다. 기본값은 `1%`입니다.
mmap_min_addr
587-599user process가 mmap하지 못하도록 제한할 address space 양입니다. kernel null dereference bug가 memory의 첫 몇 page에 있는 정보를 잘못 사용할 수 있으므로 userspace process가 그 영역에 쓰지 못하게 방어합니다.
기본값은 `0`이어서 security module이 보호를 강제하지 않습니다. `64k` 정도로 설정하면 대부분 application을 정상 동작시키면서 잠재적인 미래 kernel bug에 defense in depth를 제공합니다.
mmap_rnd_bits
600-612address space randomization 조정을 지원하는 architecture에서 mmap allocation으로 생긴 VMA region의 base address random offset에 사용할 bit 수를 고릅니다. 값은 architecture가 지원하는 최솟값과 최댓값 사이로 제한됩니다.
boot 뒤 `/proc/sys/vm/mmap_rnd_bits` tunable로 변경할 수 있습니다.
mmap_rnd_compat_bits
613-626address space randomization 조정을 지원하는 architecture에서 compatibility mode application의 mmap allocation으로 생긴 VMA region base address random offset에 사용할 bit 수입니다. architecture 지원 범위로 제한됩니다.
boot 뒤 `/proc/sys/vm/mmap_rnd_compat_bits` tunable로 변경할 수 있습니다.
nr_hugepages
627-634hugepage pool의 최소 크기를 바꿉니다. 자세한 내용은 `Documentation/admin-guide/mm/hugetlbpage.rst`를 참조하십시오.
hugetlb_optimize_vmemmap
635-671`include/linux/mm_types.h`에 정의된 `struct page` 크기가 2의 거듭제곱이 아닌 드문 system 구성에서는 이 knob가 제공되지 않습니다. `1`은 HugeTLB Vmemmap Optimization(HVO)을 활성화하고 `0`은 비활성화합니다.
활성화하면 이후 buddy allocator에서 할당되는 HugeTLB page의 vmemmap page가 최적화됩니다. 절감량은 2MB HugeTLB page당 7 page, 1GB HugeTLB page당 4095 page이며 이미 할당된 HugeTLB page는 바뀌지 않습니다.
최적화한 HugeTLB page를 pool에서 buddy allocator로 반환할 때는 해당 범위를 나타내는 vmemmap을 다시 map하고 앞서 버린 vmemmap page를 다시 할당해야 합니다. `nr_hugepages`로 미리 만들지 않고 `nr_overcommit_hugepages`만 설정해 page를 `on the fly`로 할당하는 workload라면 memory 절감과 allocation/free overhead 증가, 약 2배 느려질 수 있는 비용을 비교해야 합니다.
심한 memory pressure에서는 vmemmap page allocation이 실패해 HugeTLB page를 pool에서 buddy allocator로 해제하지 못할 수 있으며 이 경우 나중에 재시도해야 합니다.
비활성화하면 이후 buddy allocator에서 할당되는 HugeTLB page는 최적화되지 않아 allocation 시 추가 overhead가 사라지지만 기존 최적화 page는 그대로입니다. 최적화 page를 모두 없애려면 먼저 `nr_hugepages`를 `0`으로 만든 뒤 이 설정을 끌 수 있습니다.
다만 사용 중인 HugeTLB page는 `nr_hugepages`에 0을 써도 surplus page가 되며, 사용이 끝나 release될 때까지 최적화 상태입니다. system에서 최적화 page가 완전히 사라지려면 그 release를 기다려야 합니다.
nr_hugepages_mempolicy
672-680특정 NUMA node 집합에서 runtime 중 hugepage pool 크기를 바꿉니다. 자세한 내용은 `Documentation/admin-guide/mm/hugetlbpage.rst`를 참조하십시오.
nr_overcommit_hugepages
681-689hugepage pool의 최대 크기를 바꿉니다. 최대치는 `nr_hugepages + nr_overcommit_hugepages`입니다. 자세한 내용은 `Documentation/admin-guide/mm/hugetlbpage.rst`를 참조하십시오.
nr_trim_pages
690-706`CONFIG_MMU=n`인 NOMMU kernel에서만 제공되며, 2의 거듭제곱으로 정렬된 NOMMU mmap allocation의 excess page trimming 동작을 조정합니다.
`0`은 trimming을 완전히 끄고 `1`은 excess page를 적극적으로 trim합니다. `1` 이상의 값은 allocation trimming을 시작하는 watermark로 동작하며 기본값은 `1`입니다. 자세한 내용은 `Documentation/admin-guide/mm/nommu-mmap.rst`를 참조하십시오.
numa_zonelist_order
707-755NUMA 전용이며 deprecated된 sysctl입니다. `Node` order 이외의 값은 실패합니다. memory가 어디서 할당되는지는 zonelist가 제어하며, 설명을 단순화하기 위해 `ZONE_HIGHMEM`과 `ZONE_DMA32`는 생략합니다.
non-NUMA에서 `GFP_KERNEL` zonelist는 `ZONE_NORMAL -> ZONE_DMA` 순서입니다. `ZONE_NORMAL`을 사용할 수 없을 때만 `ZONE_DMA`에서 할당한다는 뜻입니다.
2-node NUMA에서 Node(0)의 `GFP_KERNEL` zonelist는 다음 두 순서를 생각할 수 있습니다.
(A) Node(0) ZONE_NORMAL -> Node(0) ZONE_DMA -> Node(1) ZONE_NORMAL
(B) Node(0) ZONE_NORMAL -> Node(1) ZONE_NORMAL -> Node(0) ZONE_DMA.
(A)는 Node(0) process에 가장 좋은 locality를 제공하지만 `ZONE_NORMAL` 고갈 전에 작은 `ZONE_DMA`를 써서 DMA zone OOM 가능성을 높입니다. (B)는 locality가 덜 좋지만 DMA zone OOM에 더 견고합니다.
| 요청값 | 순서 |
|---|---|
| `[Nn]ode` | node 순서, 각 node 안에서 zone 순서 |
| `[Zz]one` | zone type 순서, 각 zone 안에서 node 순서 |
| `[Dd]efault` | 자동 구성 요청 |
32-bit에서는 kernel이 접근할 Normal zone을 보존해야 하므로 `zone` order가 선택됩니다. 64-bit에서는 DMA32/DMA가 필요한 device가 비교적 드물어 `node` order가 선택됩니다. system/application 문제를 일으키지 않는 한 default order가 권장됩니다.
oom_dump_tasks
756-777kernel이 OOM kill을 수행할 때 kernel thread를 제외한 system-wide task dump를 만들지 정합니다. dump에는 `pid`, `uid`, `tgid`, VM size, RSS, `pgtables_bytes`, `swapents`, `oom_score_adj` score, 이름 등이 포함됩니다.
OOM killer가 호출된 이유, 문제를 일으킨 task, 종료 대상으로 고른 이유를 분석하는 데 유용합니다. `0`이면 정보를 숨기며, task가 수천 개인 큰 system에서는 OOM 상황의 성능 비용을 피하려고 끌 수 있습니다.
0이 아니면 OOM killer가 실제로 memory를 과도하게 쓰는 task를 종료할 때 정보를 표시합니다. 기본값은 `1`(활성화)입니다.
oom_kill_allocating_task
778-798out-of-memory 상황에서 OOM을 trigger한 task 자체를 종료할지 정합니다. `0`이면 OOM killer가 전체 task list를 scan하고 heuristic으로 대상을 고릅니다. 보통 종료했을 때 많은 memory를 해제하는 문제 task를 선택합니다.
0이 아니면 OOM condition을 trigger한 task를 바로 종료해 비싼 task list scan을 피합니다. `panic_on_oom`을 선택했다면 이 값보다 우선합니다. 기본값은 `0`입니다.
overcommit_kbytes
799-809`overcommit_memory=2`일 때 committed address space가 swap과 이 값만큼의 physical RAM을 합친 크기를 넘지 못하게 합니다.
`overcommit_ratio`와 짝을 이루며 둘 중 하나만 지정할 수 있습니다. 하나를 설정하면 다른 설정은 비활성화되어 읽을 때 `0`으로 보입니다.
overcommit_memory
810-834memory overcommitment policy를 고르는 flag입니다.
| 값 | 동작 |
|---|---|
| `0` | userspace memory request를 total memory와 swap에 비교해 명백한 overcommit을 거부하는 기본 heuristic mode |
| `1` | 실제로 memory가 바닥날 때까지 항상 충분한 memory가 있다고 간주 |
| `2` | memory overcommit을 막으려는 `never overcommit` policy. `user_reserve_kbytes`의 영향을 받음 |
많은 program이 `just-in-case`로 매우 큰 memory를 `malloc()`하지만 실제 사용량은 적기 때문에 이 기능이 유용할 수 있습니다. 기본값은 `0`입니다.
자세한 내용은 `Documentation/mm/overcommit-accounting.rst`와 `mm/util.c::__vm_enough_memory()`를 참조하십시오.
overcommit_ratio
835-842`overcommit_memory=2`일 때 committed address space가 swap과 이 백분율만큼의 physical RAM을 합친 크기를 넘지 못하게 합니다.
page-cluster
843-864한 번에 swap에서 읽어 오는 연속 page의 최대 개수를 제어하며 page cache readahead의 swap 대응 항목입니다. 여기서 연속은 virtual/physical address가 아니라 swap space에서 함께 swap out된 순서를 뜻합니다.
logarithmic value이므로 `0`은 1 page, `1`은 2 page, `2`는 4 page를 뜻합니다. `0`은 swap readahead를 완전히 끕니다. 기본값은 `3`, 즉 한 번에 8 page입니다.
swap 사용이 많은 workload에서는 조정 효과가 조금 있을 수 있습니다. 낮은 값은 최초 fault latency를 낮추지만, readahead로 함께 들어왔을 후속 page에 추가 fault와 I/O delay를 만들 수 있습니다.
page_lock_unfairness
865-872waiter 앞에서 page lock을 빼앗을 수 있는 횟수를 정합니다. 이 횟수만큼 lock이 steal된 뒤에는 `fair lock handoff` semantics를 적용해 lock을 실제로 얻을 수 있을 때만 waiter를 깨웁니다. 기본값은 `5`입니다.
panic_on_oom
873-901out-of-memory 발생 시 panic할지 정합니다.
| 값 | 동작 |
|---|---|
| `0` | OOM killer가 문제 process를 종료. 보통 system은 생존하며 기본값 |
| `1` | OOM이면 panic. 다만 mempolicy/cpuset으로 제한된 node만 고갈되고 다른 node에 memory가 남은 경우에는 process 하나만 종료할 수 있으며 panic하지 않음 |
| `2` | 위와 같은 제한된 node OOM이나 memory cgroup OOM에서도 system 전체를 강제로 panic |
`1`과 `2`는 cluster failover 정책을 위한 값이므로 정책에 맞게 선택합니다. `panic_on_oom=2`와 kdump를 함께 쓰면 OOM 원인을 조사할 snapshot을 얻을 수 있습니다.
percpu_pagelist_high_fraction
902-921각 zone page 중 per-CPU page list에 저장할 수 있는 비율의 분모입니다. online CPU 수에 따라 나뉘는 상한이며 최솟값은 `8`, 즉 각 zone page의 `1/8`보다 많이 per-CPU list에 두지 못합니다. hot per-CPU page list 값만 바꿉니다.
예를 들어 `100`은 각 zone의 `1/100`을 per-CPU list 사이에 배분합니다. high fraction과 무관하게 각 list의 batch 값은 유지되므로 allocation latency에는 영향이 없습니다.
초깃값은 `0`입니다. 이때 kernel은 zone의 low watermark와 local online CPU 수를 바탕으로 high `pcp->high` mark를 정합니다. 사용자가 다시 `0`을 쓰면 이 기본 동작으로 돌아갑니다.
stat_interval
922-928VM statistics를 갱신하는 시간 간격이며 기본값은 1초입니다.
stat_refresh
929-941root만 읽거나 쓸 수 있으며 어느 쪽을 수행해도 CPU별 VM statistics를 모두 global total로 flush합니다. 예를 들어 `cat /proc/sys/vm/stat_refresh /proc/meminfo`로 test report의 정확도를 높일 수 있습니다.
부수적으로 다른 곳에서는 0으로 보고되는 negative total도 검사하고, 발견하면 dmesg warning과 함께 `EINVAL`로 실패합니다. 원문 작성 시점에 부작용 없이 가끔 negative가 되는 것으로 알려진 일부 stat은 error와 warning을 억제합니다.
numa_stat
942-958NUMA statistics를 runtime에 구성합니다. page allocation 성능이 bottleneck이고 tool 일부가 고장나거나 NUMA counter precision이 낮아질 수 있음을 감수한다면 다음과 같이 끕니다.
echo 0 > /proc/sys/vm/numa_stat
page allocation 성능이 bottleneck이 아니고 모든 tooling의 동작이 필요하다면 다음과 같이 켭니다.
echo 1 > /proc/sys/vm/numa_stat
swappiness
959-983swap과 filesystem paging의 대략적인 상대 I/O 비용을 `0`에서 `200` 사이 값으로 표현합니다. `100`이면 VM이 두 I/O 비용을 같게 보고 page cache와 swap-backed page에 동일하게 memory pressure를 적용합니다. 낮으면 swap I/O가 더 비싸고 높으면 더 저렴하다는 뜻입니다.
memory pressure 아래에서 filesystem I/O pattern은 swap의 random I/O보다 효율적인 경향이 있으므로 최적값은 workload별 실험이 필요합니다. 기본값은 `60`입니다.
zram·zswap 같은 in-memory swap이나 filesystem보다 빠른 device에 swap이 있는 hybrid 구성은 `100` 초과도 고려할 수 있습니다. 예를 들어 swap random I/O가 filesystem I/O보다 평균 2배 빠르면 `x + 2x = 200`, `2x = 133.33`이므로 `swappiness=133`이 됩니다.
`0`이면 zone의 free page와 file-backed page 합계가 high watermark보다 작아질 때까지 kernel이 swap을 시작하지 않습니다.
unprivileged_userfaultfd
984-1002unprivileged user가 `userfaultfd` system call을 사용할 수 있는 mode를 제어합니다. `0`이면 user mode page fault만 처리하도록 제한합니다. 이 경우 `SYS_CAP_PTRACE`가 없는 사용자는 `userfaultfd`가 성공하도록 `UFFD_USER_MODE_ONLY`를 전달해야 합니다.
kernel mode fault 처리에 `userfaultfd`를 쓰지 못하게 하면 일부 vulnerability exploit을 어렵게 만들 수 있습니다. `1`은 unprivileged user에게 제한 없는 system call 사용을 허용합니다. 기본값은 `0`입니다.
권한을 제어하는 다른 방법은 `userfaultfd(2)` 대신 `/dev/userfaultfd`를 사용하는 것입니다. `Documentation/admin-guide/mm/userfaultfd.rst`를 참조하십시오.
user_reserve_kbytes
1003-1020`overcommit_memory=2`인 `never overcommit` mode에서 free memory 중 `min(current process size의 3%, user_reserve_kbytes)`를 보존합니다. 사용자가 process 하나로 memory를 독점해 그 process를 종료할 복구 명령조차 실행하지 못하는 일을 막습니다.
기본값은 `min(current process size의 3%, 128MB)`입니다. `0`으로 줄이면 사용자가 단일 process로 `admin_reserve_kbytes`를 제외한 모든 free memory를 할당할 수 있고, 이후 command 실행은 `fork: Cannot allocate memory`가 됩니다. 변경은 application이 memory를 요청할 때마다 적용됩니다.
vfs_cache_pressure
1021-1043directory와 inode object cache에 쓰인 memory를 kernel이 회수하려는 경향을 백분율로 제어합니다. 기본값 `vfs_cache_pressure=vfs_cache_pressure_denom`에서는 pagecache와 swapcache reclaim에 비해 dentry·inode를 `fair`한 비율로 회수합니다.
낮추면 dentry와 inode cache를 더 오래 유지합니다. `vfs_cache_pressure=0`이면 memory pressure 때문에 이를 회수하지 않아 쉽게 OOM이 될 수 있습니다. `vfs_cache_pressure_denom`보다 높이면 dentry와 inode 회수를 선호합니다.
분모보다 지나치게 높이면 free 가능한 directory와 inode object를 찾는 reclaim code가 여러 lock을 잡아 성능이 나빠질 수 있습니다. 값이 `10 * vfs_cache_pressure_denom`이면 실제 수보다 10배 많은 freeable object를 찾습니다. 항상 `vfs_cache_pressure_denom`과 함께 사용해야 합니다.
vfs_cache_pressure_denom
1044-1049기본값이자 허용 최솟값은 `100`입니다. 효과를 내려면 대응하는 `vfs_cache_pressure`도 설정해야 합니다.
watermark_boost_factor
1050-1069memory가 fragmented될 때 reclaim 수준을 제어합니다. mobility가 다른 page가 pageblock 안에서 섞이면 zone high watermark의 몇 퍼센트까지 회수할지 정합니다. 이후 compaction 작업을 줄이고 SLUB allocation, THP, hugetlbfs page 같은 higher-order allocation 성공률을 높이는 목적입니다.
`watermark_scale_factor`와 맞추기 위해 단위는 10,000분율입니다. 기본값 `15000`은 fragmentation 때문에 pageblock이 섞인 경우 high watermark의 최대 150%까지 회수한다는 뜻이며 실제 수준은 최근 fragmentation event 수로 정합니다.
계산값이 pageblock보다 작으면 pageblock 하나 분량, 예를 들어 64-bit x86에서 2MB를 회수합니다. `0`은 기능을 비활성화합니다.
watermark_scale_factor
1070-1087`kswapd`의 적극성을 제어합니다. kswapd를 깨우기 전 node/system에 남겨 둘 memory와 다시 sleep하기 전에 확보해야 할 free memory 양을 정합니다.
단위는 10,000분율입니다. 기본값 `10`은 watermark 사이 거리가 node/system available memory의 0.1%라는 뜻입니다. 최댓값은 `3000`, 즉 memory의 30%입니다.
direct reclaim에 들어가는 thread 비율 `allocstall`이 높거나 `kswapd_low_wmark_hit_quickly` 때문에 kswapd가 너무 일찍 sleep한다면 allocation burst의 latency를 감당할 free page가 부족하다는 신호일 수 있습니다. 이 knob로 kswapd aggressiveness를 조정할 수 있습니다.
zone_reclaim_mode
1088-1125zone의 memory가 바닥났을 때 얼마나 적극적으로 memory를 reclaim할지 정합니다. `0`이면 zone reclaim을 하지 않고 system의 다른 zone/node에서 allocation을 만족합니다.
| bit | 동작 |
|---|---|
| `1` | zone reclaim 활성화 |
| `2` | zone reclaim이 dirty page를 writeout |
| `4` | zone reclaim이 page를 swap |
값은 bitwise OR로 조합합니다. 기본값은 비활성화입니다. file server나 data cache 효과가 중요한 workload에서는 locality보다 cache가 더 중요할 가능성이 크므로 끈 상태가 적합합니다.
각 workload partition이 NUMA node 하나에 들어가고 remote memory access가 측정 가능한 성능 저하를 일으킨다고 알려진 경우 하나 이상의 bit 활성화를 고려합니다. page allocator는 off-node page를 할당하기 전에 추가 조치를 합니다.
writeout을 허용하면 많은 data를 쓰는 process가 다른 node의 page까지 dirty하게 만드는 일을 막습니다. zone이 차면 dirty page를 기록해 process를 사실상 throttle합니다. 단일 process가 outgoing write buffer로 system memory 전체를 쓰지 못해 느려질 수 있지만 다른 node의 memory와 그 node에서 실행되는 process의 성능은 보존합니다.
일반 swap을 허용하면 memory policy나 cpuset configuration으로 명시적으로 override하지 않는 한 allocation을 local node로 사실상 제한합니다.
요약과 해설
vm.rst:1-1125VM sysctl은 단순 성능 knob가 아니라 memory allocation의 성공 조건, dirty data가 disk로 나가는 시점, OOM 시 process 또는 system 전체의 운명까지 바꿉니다. 운영 변경 전에는 workload의 memory locality, swap 장치 특성, HugeTLB 사용 방식, 장애 복구 정책을 함께 확인해야 합니다.
`drop_caches`는 cache 성장 제어 수단이 아니며, `min_free_kbytes`, `panic_on_oom`, `zone_reclaim_mode` 같은 값을 극단적으로 바꾸면 즉시 OOM, 불필요한 panic, I/O throttling 또는 latency spike가 생길 수 있습니다. 원문의 단위와 기본값을 기준으로 작은 단계로 조정하고 VM/OOM 통계를 함께 관찰해야 합니다.