由于伙伴算法的存在,linux的内存势必出现碎片,虽然大多数时候不会对应用层产生影响,但是一旦遇到需要连续内存的情况就歇逼了;
这时候就需要整理内存碎片
实际问题场景:
cat /proc/buddyinfoNode 0, zone DMA 182 167 132 32 0 0 0 0 0 0 0Node 0, zone Normal 846 1998 1043 464 154 69 15 3 3 1 0
/proc/buddyinfo这个文件记录了物理内存的状态,linux会使用一个长度为11的链表维护pages
从这个文件可以看出DMA碎片化已经很严重了,大多数内存都变成page=1 page=2 page=4的小块连续内存;
此时需要整理内存;
触发内存碎片整理的三种方法:
内存分配时整理:
调用过程如下:
alloc_pages_slowpath
\
alloc_pages_direct_compact
\
__try_to_compact_pages
\
compact_zone_order
\
compact_zone
Kcompactd后台进程进行整理
调用过程如下:
kcompactd -> kcompactd_do_work -> compact_zone
手动触发碎片整理
触发方式:
echo 1 > /sys/devices/system/node/node0/compact
(sysfs_compact_node -> compact_node -> compact -> compact_zone)
echo 1 > /proc/sys/vm/compact_memory
(sysctl_compaction_handler -> compact_nodes -> compact -> compact_zone)
