本文共 1891 字,大约阅读时间需要 6 分钟。
mem_cgroup(内核内存控制组)是内核中用于实现进程内存隔离的一种重要机制。它为系统管理员提供了对内核空间内存的细粒度控制能力。通过将进程划分到不同的mem_cgroup,管理员可以根据需求限制每个组的内存使用范围。这一机制在内核空间内存管理中发挥着关键作用。
mem_cgroup在内核中通过cgroup(控制组)框架实现。每个mem_cgroup都有自己的内存限制参数,包括:
这两个限制参数共同决定了一个mem_cgroup能够占用的内存总量。需要注意的是,memsw总是大于或等于res,因为交换区可以为物理内存提供额外的内存空间。
mem_cgroup在内核中采用树型结构管理。一个mem_cgroup可以包含多个子mem_cgroup(通过hierarchy参数控制),形成一个层级结构。这种结构使得内核在内存管理时能够按照树的层次逐步处理每个子组。
为了实现内存隔离,mem_cgroup需要统计组内进程使用的内存量。内核通过以下方式实现这一功能:
通过这些结构体,内核可以跟踪每个内存页面和swap entry所属的mem_cgroup,进而统计每个mem_cgroup的内存使用情况。
内核对内存使用的计数分为两种类型:
内核在进程使用或释放这些内存类型时,会分别触发对应的计数操作:
内核在内存不足时通过reclaim流程回收不再需要的内存页面。mem_cgroup的内存回收流程与全局内存管理方式类似,但增加了对 mem_cgroup的支持,使得回收过程可以按组别进行。
每个 mem_cgroup维护一个lru列表,用于跟踪组内最不常用的页面。内核在需要回收内存时,首先尝试回收lru列表中的页面。
当 mem_cgroup的内存使用超出硬限制(hard_limit)时,内核会进入OOM流程,尝试回收足够的内存。如果无法回收足够的内存,内核会选择一个进程进行杀死,以释放内存空间。
内核在选择要杀死的进程时,会综合考虑多个因素:
删除一个 mem_cgroup需要满足以下条件:
删除操作会将 mem_cgroup的计数添加到其父 mem_cgroup,同时释放组内的所有内存页面。
进程在 mem_cgroup之间迁移需要谨慎处理。默认情况下,迁移操作不会触发 charge或uncharge操作,但可以通过设置 move_charge_at_immigrate 参数来控制迁移时的计数行为。
为了减少内核在多核系统中的竞争,内核引入了 per-CPU缓存机制。每个 CPU维护一个 memcg_stock_pcp 缓存,用于本地处理 charge和uncharge操作,避免多个 CPU同时对同一个 mem_cgroup进行操作带来的竞争。
mem_cgroup作为内核中重要的内存管理机制,为系统管理员提供了强大的内存隔离能力。通过合理配置 mem_cgroup,管理员可以根据系统需求,限制不同组的内存使用范围,从而优化系统性能。
转载地址:http://htzfk.baihongyu.com/