首页 > 系统相关 >迁移类型与内存碎片

迁移类型与内存碎片

时间:2023-10-08 11:15:49浏览次数:36  
标签:MIGRATE 碎片 内存 类型 迁移 移动 分配 RESERVE

前言

在伙伴系统中长时间的内存分配之后很容易造成内存碎片,即物理内存总量不少但是无法合并为大的连续内存块。而在现代CPU中提供了huge page的可能,可以分配超大块的page,在TLB中使用更少级的地址转换操作。一个page覆盖了更大的地址范围,大幅度的提高了TLB的命中概率。对于内存密集型应用来说使用巨页能够有效提高性能。huge page的分配自然需要连续的内存区域。因此避免内存碎片对于需要分配大块内存分配的场景来说非常重要。
Note:这里的内存碎片指的以页为粒度的碎片,迁移类型是在伙伴系统层面避免碎片产生的一种机制。

已分配Page类型

在Linux内核中将已分配的page被划分为以下三种类型:

  • 不可移动页:不可以移动的页,内核分配的Page属于该类型,因为内核分配的Page的页表采取的是直接映射,这些页移动后无法通过更改页表映射来进行重定向。
  • 可回收页:该类型页不可以移动,但是可以回收(删除内容),其内容可以从某些源重新生成,比如文件映射。当内存中可回收页过多就会唤醒kswapd进行内存回收。
  • 可移动页:可以任意移动,用户空间分配的内存属于该种类型,这种page通过页表建立映射,移动后只需要重新建立映射即可。

为了避免不可移动页出现在可移动页之间,导致大块内存不可使用,在内核启动时将所有伙伴系统中所有内存页划分为了不同的迁移类型,每类内存包含一定数量的页,在内存分配时可以选择指定迁移类型的内存块,这样就不会出现不可移动的页出现在了可移动页的内部,导致无法通过页面迁移来进行内存规整。

伙伴系统和迁移类型

在伙伴系统中每个分配阶的自由链表都有多个,struct free_area中的每个自由链表对应一种迁移类型。

struct zone {
    struct free_area free_area[MAX_ORDER];
}

struct free_area {
    struct list_head free_list[MIGRATE_TYPES];
    unsigned long  nr_free;
};

内核支持的迁移类型包括以下五种,MIGRATE_UNMOVABLE表示不可移动,MIGRATE_RECLAIMABLE对应可回收,MIGRATE_MOVABLE对应可移动,MIGRATE_RESERVE对应保留内存,这部分用于紧急情况的内存分配。MIGRATE_ISOLATE无法分配。

#define MIGRATE_UNMOVABLE     0
#define MIGRATE_RECLAIMABLE   1
#define MIGRATE_MOVABLE       2
#define MIGRATE_RESERVE       3
#define MIGRATE_ISOLATE       4 /* can't allocate from here */
#define MIGRATE_TYPES         5

当内存分配在指定的迁移类型列表中无法完成分配时会按照备选列表的顺序选择其他迁移类型的自由链表继续内存分配。

static int fallbacks[MIGRATE_TYPES][MIGRATE_TYPES-1] = {
    [MIGRATE_UNMOVABLE]   = { MIGRATE_RECLAIMABLE, MIGRATE_MOVABLE,   MIGRATE_RESERVE },
    [MIGRATE_RECLAIMABLE] = { MIGRATE_UNMOVABLE,   MIGRATE_MOVABLE,   MIGRATE_RESERVE },
    [MIGRATE_MOVABLE]     = { MIGRATE_RECLAIMABLE, MIGRATE_UNMOVABLE, MIGRATE_RESERVE },
    [MIGRATE_RESERVE]     = { MIGRATE_RESERVE,     MIGRATE_RESERVE,   MIGRATE_RESERVE }, /* Never used */
};

这里有一个问题是,为什么备选列表的分配顺序是这样的?首先MIGRATE_RESERVE不必多说,这种类型的内存非必要情况下不分配,因此始终处于备选最后一个选项。而MIGRATE_UNMOVABLEMIGRATE_RECLAIMABLE分配失败时会偏向于靠后分配可移动内存,这是我们这个机制的目标要求的,避免在可移动内存中引入不可移动的内存,减少内存碎片的产生。而MIGRATE_MOVABLE分配失败时会优先从可回收的内存中分配,我的理解是不可移动内存的数量更稀缺,而可回收内存内存由于其特性,可以反复使用紧急程度更低。

总结

迁移类型对伙伴系统中的自由链表进行分类,从分配机制上减少了出现页间内存碎片的概率,但是并不是完全避免了。毕竟内存分配成功是第一要务,当内存不足时依然会引入内存碎片。

标签:MIGRATE,碎片,内存,类型,迁移,移动,分配,RESERVE
From: https://www.cnblogs.com/wodemia/p/17748399.html

相关文章

  • 基于 Linux、C++实现的高性能内存池
    1.引入内存池的意义  内存池(MemoryPool)是一种内存分配方式,又被称为固定大小区块规划(fixed-size-blocksallocation)。通常我们习惯直接使用new、malloc等API申请分配内存,但是这种方式非常容易产生内存碎片,早晚都会申请内存失败。并且在比较复杂的代码或者继承的屎山......
  • openGauss学习笔记-92 openGauss 数据库管理-内存优化表MOT管理-内存表特性-使用MOT-M
    openGauss学习笔记-92openGauss数据库管理-内存优化表MOT管理-内存表特性-使用MOT-MOT使用MOTSQL覆盖和限制MOT设计几乎能够覆盖SQL和未来特性集。例如,大多数支持标准的PostgresSQL,也支持常见的数据库特性,如存储过程、自定义函数等。下面介绍各种SQL覆盖和限制。92.1不支持......
  • 【v2v迁移】Xen2kvm 迁移-linux篇
    迁移环境:源平台:华为FusionComputeV100R006C10SPC101目标平台:基于KVM虚拟化的云平台,本文以原生的libvirt为例虚拟机:centos7.6具体操作步骤:1、在源平台导出格式为ovf的磁盘镜像导出后,得到vhd文件:centos_xen-1.vhd。将该文件传输到一个装有libvirt和相关工具套件的Linux环境......
  • 迁移虚拟机在目标主机上为目标网络配置的卸载或安全策略不同
    1、当前已连接的网络接口“Networkadapter1”无法使用网络“VMnetwork”,因为“在目标主机上为目标网络配置的卸载或安全策略不同于在源主机上为源网络配置的卸载或安全策略”  二、解决方案:检查集群内主机的虚拟交换机安全配置一致。(建议端口组名称也一致,还有字母大小......
  • openstack虚拟机跨机迁移
     1.node节点扩容#因此环境仅部署了一个compute节点,因此扩容一个compute计算节点#计算节点安装服务:#提前将yum仓库、防火墙、selinux、主机名、时间同步等配置完毕。[root@openstack-compute2~]#yuminstallcentos-release-openstack-train-y[root@openstack-......
  • 内存碎片化清理
    echo3>/proc/sys/vm/drop_caches具体来说,数字3代表同时清空页缓存(pagecache)、目录项缓存(dentries)和inode缓存(inodes)。这意味着执行echo3>/proc/sys/vm/drop_caches命令后,会清空这三种类型的缓存。这些缓存是用来加速文件系统的访问和提高性能的。通过清空这些缓存,可以释放一......
  • 从GPU的内存访问视角对比NHWC和NCHW
    NHWC和NCHW是卷积神经网络(cnn)中广泛使用的数据格式。它们决定了多维数据,如图像、点云或特征图如何存储在内存中。NHWC(样本数,高度,宽度,通道):这种格式存储数据通道在最后,是TensorFlow的默认格式。NCHW(样本数,通道,高度,宽度):通道位于高度和宽度尺寸之前,经常与PyTorch一起使用。......
  • openGauss学习笔记-91 openGauss 数据库管理-内存优化表MOT管理-内存表特性-使用MOT-M
    openGauss学习笔记-91openGauss数据库管理-内存优化表MOT管理-内存表特性-使用MOT-MOT使用MOT外部支持工具为了支持MOT,修改了以下外部openGauss工具。请确保使用的工具是最新版本。下面将介绍与MOT相关的用法。有关这些工具及其使用方法的完整说明,请参阅《工具与命令参考》。91......
  • [架构之路-25]:目标系统 - 系统软件 - bootloader uboot内存映射与启动流程
    原文:https://blog.csdn.net/HiWangWenBing/article/details/127062057目录第1章uboot概述1.1概述1.2内存映射(案例)1.3uboot在嵌入式系统启动中的位置第2章uboot启动流程(源码分析)2.1入口函数:_start2.3执行流程(文字描述)2.4初始化过程第3章uboot如何加载内核3.1v......
  • 进程栈、线程栈、内存栈、中断栈
    前言虽然我也很想讲X86_64体系,无奈这样的资料的确不多,因此本文还是本着学习的态度,探究早已经过时的X86体系。本文转载自此文,该博主对栈的数据结构、栈的作用等进行了阐述,其中涉及了函数栈帧的相关知识,这部分内容我没有转载,我仅仅转载了我感兴趣的进程栈,线程栈等部分,并在其中融入......