madvise
用户空间
核心语义对比
MADV_REMOVE
立即释放并解除文件映射
数据丢失
立即同步
释放文件页面
MADV_DONTNEED
立即释放页面
数据丢失
立即同步
强制内存释放
MADV_PAGEOUT
立即换出到交换空间
数据保留
立即同步
主动换出页面
MADV_FREE
惰性释放页面
可能丢失
延迟异步
惰性内存回收
MADV_COLD
标记为冷页面
数据保留
立即异步
调整LRU优先级
详细行为分析
MADV_REMOVE
madvise(addr, len, MADV_REMOVE);专门用于文件支持的映射
立即释放文件支持的页面缓存
对于私有映射:丢弃修改(不写回文件)
对于共享映射:将脏页写回文件后释放
后续访问从文件重新读取
MADV_DONTNEED
立即释放物理内存
清除页表项,数据立即丢失
后续访问映射到零页(匿名)或重新读取(文件)
MADV_PAGEOUT
立即将匿名页换出到交换空间
如果是脏文件页,先回写再释放
物理内存立即释放,但数据保留在存储设备
后续访问触发缺页,从交换空间换入
MADV_FREE
将页面移动到 LRU inactive 链表
只有在内存压力时才实际释放
如果页面未被修改,直接丢弃
如果页面被修改,保留到有内存压力时再直接释放,不回写数据到存储设备
MADV_COLD
将页面移动到 LRU inactive 链表(对于 MGLRU,如果匿名页没有swapcache,只是移动到第二代)
不立即释放或换出页面
在内存回收时优先回收这些页面,回写数据到存储设备
使用场景详细对比
MADV_REMOVE
文件映射的临时数据,可从文件恢复,需要立即释放内存
不重要
MADV_DONTNEED
可直接丢弃的安全敏感数据,需要立即释放内存
不重要
MADV_PAGEOUT
不常访问,需要保留数据,需要立即释放内存
重要
MADV_FREE
可直接丢弃的缓存数据,不需要立即释放内存
不重要
MADV_COLD
不常访问,需要保留数据,不需要立即释放内存
重要
内核空间
调用 madivise(MADV_PAGEOUT) 的流程
madivise(MADV_PAGEOUT) 的流程在 madvise_cold_or_pageout_pte_range() 根据不同的场景走不同分支,下面分为三个 场景进行分析,如下:
普通的 4KB swapout 到 swapfile
THP 的 2MB swapout 到 swapfile
small_size THP 的 64KB swapout 到 swapfile
将普通的 4KB swapout 到 swapfile 的流程
调用 add_to_swap() 申请 swap space 并且将 folio 与此 swap space 绑定在一起, 再调用 pageout() 将 folio 回写到刚刚申请的 swap space 对应的 swapfile 位置。
将 THP 的 2MB swapout 到 swapfile 的流程
第一次调用 add_to_swap() 申请 swap space,失败,调用 split_folio_to_list() 将 2MB 划分为 512 个 4KB 页。
因为现在都是 4KB 大小的页,所以跑普通的 4KB swapout 到 swapfile 的流程。
(同上)调用 add_to_swap() 申请 swap space 并且将 folio 与此 swap space 绑定在一起, 再调用 pageout() 将 folio 回写到刚刚申请的 swap space 对应的 swapfile 位置。
将 small_sized THP 的 64KB swapout 到 swapfile 的流程
Last updated
Was this helpful?