Linux内存管理-内存规整

本文深入探讨Linux内存管理中的内存规整,分析内存碎片产生的原因及内存规整的触发条件。通过调整/proc/sys/vm/compact_memory和extfrag_threshold等节点,控制内存规整行为。讲解内存规整的实现机制,包括页面迁移、zone水位判断,以及关键函数如compact_zone和isolate_migratepages的作用。了解内存规整对于优化系统性能和物理内存分配的重要性。
摘要由CSDN通过智能技术生成

内存碎片的产生:伙伴系统以页为单位进行管理,经过大量申请释放,造成大量离散且不连续的页面。这时就产生了很多碎片。

内存规整也即内存碎片整理,内存碎片也是以页面为单位的。实现基础是内存页面按照可移动性进行分组。内存规整的实现基础是页面迁移。

Linux内核以pageblock为单位来管理页的迁移属性。

为什么需要内存规整?

有些情况下,物理设备需要大段连续物理内存。虽然此时空闲内存足够,但是哟与无法找到连续的物理内存,仍然造成内存分配失败。

1. 内存规整的触发

下面是内存页面分配,以及分配失败之后采取的措施,以便促成分配成功。

可以看出采取的措施,越来越重。首先采用kswapd来进行页面回收,然后尝试页面规整、直接页面回收,最后是OOM杀死进程来获取更多内存空间。

alloc_pages-------------------------------------页面分配的入口
  ->__alloc_pages_nodemask
    ->get_page_from_freelist--------------------直接从zonelist的空闲列表中分配页面
    ->__alloc_pages_slowpath--------------------在初次尝试分配失败后,进入slowpath路径分配页面
      ->wake_all_kswapds------------------------唤醒kswapd内核线程进行页面回收
      ->get_page_from_freelist------------------kswapd页面回收后再次进行页面分配
      ->__alloc_pages_direct_compact------------进行页面规整,然后进行页面分配
      ->__alloc_pages_direct_reclaim------------直接页面回收,然后进行页面分配
      ->__alloc_pages_may_oom-------------------尝试触发OOM

另一条路径是在kswapd的balance_pgdat中会判断是否需要进行内存规整。

kswapd
  ->balance_pgdat-------------------------------遍历内存节点的zone,判断是否处于平衡状态即WMARK_HIGH。
    ->compact_pgdat-----------------------------针对整个内存节点进行内存规整

其中compact_pddat->__compact_pgdat->compact_zone,最终的实现和__alloc_pages_direct_compact调用compact_zone一样。

1.1 内存规整相关节点

内存规整相关有两个节点,compact_memory用于触发内存规整;extfrag_threshold影响内核决策是采用内存规整还是直接回收来满足大内存分配。

节点入口代码:

static struct ctl_table vm_table[] = {
...
#ifdef CONFIG_COMPACTION
    {
        .procname    = "compact_memory",
        .data        = &sysctl_compact_memory,
        .maxlen        = sizeof(int),
        .mode        = 0200,
        .proc_handler    = sysctl_compaction_handler,
    },
    {
        .procname    = "extfrag_threshold",
        .data        = &sysctl_extfrag_threshold,
        .maxlen        = sizeof(int),
        .mode        = 0644,
        .proc_handler    = sysctl_extfrag_handler,
        .extra1        = &min_extfrag_threshold,
        .extra2        = &max_extfrag_threshold,
    },

#endif /* CONFIG_COMPACTION */
...
    { }
}

1.1.1 /proc/sys/vm/compact_memory

打开compaction Tracepoint:echo 1 > /sys/kernel/debug/tracing/events/compaction/enable

触发内存规整:sysctl -w vm.compact_memory=1

查看Tracepoint:cat /sys/kernel/debug/tracing/trace

1.1.2 /proc/sys/vm/extfrag_threshold

在compact_zone中调用函数compaction_suitable->__compaction_suitable进行判断是否进行内存规整。

和extfrag_threshold相关部分如下,如果当前fragindex不超过sysctl_extfrag_threshold,则不会继续进行内存规整。

所以这个参数越小越倾向于进行内存规整,越大越不容易进行内存规整。

static unsigned long __compaction_suitable(struct zone *zone, int order,
                    int alloc_flags, int classzone_idx)
{
...
    fragindex = fragmentation_index(zone, order);
    if (fragindex >= 0 && fragindex <= sysctl_extfrag_threshold)
        return COMPACT_NOT_SUITABLE_ZONE;

    return COMPACT_CONTINUE;
}

设置extfrag_threshold:sysctl -w vm.extfrag_threshold=500

1.1.3 其它Debug信息

/sys/kernel/debug/extfrag/extfrag_index

/sys/kernel/debug/extfrag/unusable_index

【文章福利】小编推荐自己的Linux内核技术交流群: 【977878001】整理一些个人觉得比较好得学习书籍、视频资料共享在群文件里面,有需要的可以自行添加哦!!!前100进群领取,额外赠送一份 价值699的内核资料包(含视频教程、电子书、实战项目及代码)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值