要确认 swap 的是 anon page 还是 file-backed page,需结合 /proc/vmstat 中的 pswpin/pswpout 与 /proc/*/smaps 的 Swap 字段,并用 pmap -x 观察 ANON 和 SWAP 列是否同步增长:若 ANON 高且 SWAP 同步上升,则为 anon page 被 swap。
怎么确认 swap 的到底是 anon page 还是 file-backed page
Linux 的
只影响内核在内存压力下「倾向」换出哪类页,但不禁止换出任何一类。所以即使设成
,swap 仍可能高频发生——关键得先分清:到底是谁在被 swap?
用
最直接:
/
是 I/O 页计数,不区分类型;真正要看的是
和
中的
字段,但更高效的是:
运行
,重点看
和
(单位:页),这两个是纯 swap I/O 计数
查具体进程:用
,结果是每个进程当前占用的 swap 页数(KB)
结合
看某进程的
列(匿名映射)和
列是否同步增长——如果
高且
也高,基本就是 anon page 在被 swap
为什么 swappiness=10 还会大量 swap anon page
不是开关,而是权重调节器:它控制的是「在 reclaim 时,从 anon list 和 file list 中按比例选择候选页」。当系统真的缺内存,且 anon pages 占比极高(比如 Java 堆、大 malloc 缓存),哪怕权重低,reclaim 也必须扫到它们。
典型场景:Java 应用堆设了
,但物理内存只剩 2G 可用,此时无论
是 1 还是 100,内核都得把部分 anon page 换出
才是「尽量不 swap anon」,但它不等于「禁止」,仅表示:只有在 file cache 几乎清空后,才考虑 anon;而
仍会给 anon 分配约 10% 的回收机会
注意:如果
显示为 10,但
是 2(严格模式),且
设得太小,也会导致 malloc 失败前被迫提前 swap
file-backed page 被 swap 的常见诱因
file-backed page(如 mmap 的普通文件、共享库)本不该常驻 swap,因为它们有磁盘源,可直接丢弃或重读。但以下情况会让它们进 swap:
Eclipse导入Android或其他的JAVA项目的正确方法 WORD版
本文档主要讲述的是Eclipse导入Android或其他的JAVA项目的正确方法;希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看
下载
进程对 mmap 文件做了
+ 写操作 → 触发 COW,生成私有 dirty anon page,这部分就归入 anon list,后续可能被 swap
tmpfs/shm 使用过量(比如
被塞满),tmpfs 页面本质是 file-backed,但内存不足时会被当作 anon 处理并 swap
ext4/xfs 的 delayed allocation + 大量未刷盘 dirty page,在内存紧张时,内核可能先把它们标记为 swap candidate(尤其配合
偏高时)
验证方法:用
查大 tmpfs 文件;用
看有多少私有写时复制映射。
排查时最容易忽略的三个点
很多同学盯着
调来调去,却漏掉底层约束:
设得太低,会导致 kswapd 过早唤醒,频繁扫描页表,放大 swap 行为——建议设为物理内存的 1%~2%
和
若设得过高(比如 40/10),会使脏页堆积,间接抬高内存水位,触发更激进的 reclaim
NUMA 架构下,
启动的进程若只绑定了
node
0,但 node 0 内存耗尽,node 1 又没被允许访问,就会强行 swap,而不是跨 node 分配
swap 频繁从来不是单一参数问题,而是内存分配路径、页面生命周期、I/O 压力三者咬合的结果。改
前,先看
是否真在涨,再确认涨的是谁的
字段——否则调再低也没用。
swappinessswappiness=10/proc/vmstatpgpginpgpgoutpgmajfault/proc/*/smapsSwapcat /proc/vmstat | grep -E "pgpg|pgmaj|pgpg"pswpinpswpoutawk '/^Swap:/ {sum += $2} END {print sum}' /proc/*/smaps 2>/dev/null | sort -n | tail -5pmap -x ANONSWAPANONSWAPswappiness-Xmx8gswappinessswappiness=0swappiness=10/proc/sys/vm/swapiness/proc/sys/vm/overcommit_memory/proc/sys/vm/overcommit_ratioMAP_PRIVATE/dev/shmvm.vfs_cache_pressurefind /dev/shm /run -type f -size +1M 2>/dev/null | xargs ls -lhgrep -i "mmapped" /proc/*/maps | wc -lswappiness/proc/sys/vm/min_free_kbytes/proc/sys/vm/dirty_ratio/proc/sys/vm/dirty_background_rationumactl --membind=0 your_appswappinesspswpoutSwap: