首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Linux内存分配策略

伙伴系统分配算法 在上一节, 我们介绍了Linux内核怎么管理系统中的物理内存....但有时候内核需要分配一些物理内存地址也连续的内存, 所以Linux使用了 伙伴系统分配算法 来管理系统中的物理内存....上一节说过, 内核使用 alloc_pages() 函数来分配内存, 而 alloc_pages() 函数最后会调用 rmqueue() 函数来分配内存, rmqueue() 函数原型如下: static...在Linux内核中, 把两个物理地址相邻的内存当作成伙伴, 因为Linux是以页面号来管理内存的, 所以就是说两个相邻页面号的页面是伙伴关系....所以, 使用伙伴系统算法只能分配 2order (order为0,1,2,3...)个页面. 那么order是不是无限大呢? 当然不是, 在Linux内核中, order的最大值是 10.

3.2K10

Linux分配器之内存碎片化整理

分配器在慢速分配中包括内存碎片化整理和内存回收,代码如下: static inline struct page * __alloc_pages_slowpath(gfp_t gfp_mask, unsigned...什么是内存碎片化 Linux物理内存碎片化包括两种:内部碎片化和外部碎片化。 内部碎片化: 指分配给用户的内存空间中未被使用的部分。...例如进程需要使用3K bytes物理内存,于是向系统申请了大小等于3Kbytes的内存,但是由于Linux内核伙伴系统算法最小颗粒是4K bytes,所以分配的是4Kbytes内存,那么其中1K bytes...外部碎片化: 指系统中无法利用的小内存块。例如系统剩余内存为16K bytes,但是这16K bytes内存是由4个4K bytes的页面组成,即16K内存物理帧号#1不连续。...蓝色表示空闲的页面,白色表示已经被分配的页面,可以看到如上内存域的空闲页面(蓝色)非常零散,无法分配大于两的连续物理内存

2.6K20
您找到你想要的搜索结果了吗?
是的
没有找到

Linux 内核 内存管理】内存映射原理 ② ( 内存映射概念 | 文件映射 | 匿名映射 | 内存映射原理 | 分配虚拟内存 | 产生缺页异常 | 分配物理内存 | 共享内存 | 进程内存 )

文章目录 一、内存映射概念 二、内存映射原理 1、分配虚拟内存 2、产生缺页异常 3、分配物理内存 三、共享内存 四、进程内存段的内存映射类型 一、内存映射概念 ---- 内存映射 概念 : "..." 物理内存空间 “ 映射到 ” 虚拟内存空间 " , 其中的数据是随机值 ; 二、内存映射原理 ---- 1、分配虚拟内存 分配 虚拟内存 : 在 Linux 系统中 创建 " 内存映射 “ 时..., 会在 ” 用户虚拟地址空间 “ 中 , 分配一块 ” 虚拟内存区域 " ; 2、产生缺页异常 缺页异常 : Linux 内核在分配 " 物理内存 “ 时 , 采用了 ” 延迟策略 “ , 即进程第一次访问..., 不会立即分配 物理内存 , 而是产生一个 ” 缺页异常 " ; 3、分配物理内存 分配 物理内存 : 缺页异常后的 2 种处理策略 ; 文件映射 : 对于 " 文件映射 " , 遇到 "...缺页异常 " 后 , 会 分配 " 物理内存 “ , 并且将 要映射的文件 的 部分数据 读取到 该 ” 物理内存 " 中 ; 匿名映射 : 对于 " 匿名映射 " , 直接分配 " 物理内存

8.2K20

高端内存映射之vmalloc分配内存中不连续的--Linux内存管理(十九)

1 内存中不连续的分配 根据上文的讲述, 我们知道物理上连续的映射对内核是最好的, 但并不总能成功地使用. 在分配一大块内存时, 可能竭尽全力也无法找到连续的内存块....分配到其中的可能位于物理内存中的任何地方. 通过修改负责该区域的内核表, 即可做到这一点. ? ?...v=4.7, line 1354 由于各个vmalloc子区域之间需要插入1(警戒)作为安全隙, 内核首先适当提高需要分配内存长度. static struct vm_struct *__get_vm_area_node...接下来从物理内存分配各个 最后将这些连续地映射到vmalloc区域中, 分配虚拟内存的工作就完成了....unmap_vm_area使用找到的vm_area实例,从表删除不再需要的项。与分配内存时类似,该函 数需要操作各级表,但这一次需要删除涉及的项。它还会更新CPU高速缓存。

2.9K10

Linux 内核 内存管理】内存管理架构 ③ ( Linux 内核中的内存管理模块 | 分配器 | 不连续分配器 | 内存控制组 | 硬件设备内存管理 | MMU | 表缓存 | 高速缓存 )

文章目录 一、Linux 内核中的内存管理模块 二、硬件设备内存管理 一、Linux 内核中的内存管理模块 ---- Linux 内核还需要处理如下内容 : ① 错误异常处理 ② 表管理 ③ 引导内存分配器...: 分配器 , 块分配器 , 不连续分配器 , 连续内存分配器 , 每处理器内存分配器 ; " 分配器 " 负责分配 内存物理 , 使用的是 " 伙伴分配器 " ; " 不连续分配器 " 提供了...vmalloc 函数 用于分配内存 , vfree 函数 用于 释放内存 ; 申请的 " 不连续物理 “ 可以 映射到 ” 连续的虚拟 " ; ④ 内存碎片整理 ⑤ 内存耗尽处理 ⑥ 内存控制组...: 控制管理 被 进程 占用的 内存 ; 碎片整理 : 如果 " 内存碎片化 " 严重 , 没有连续物理 , 需要通过 整理内存碎片 并迁移数据 得到 连续的 物理 ; 内存回收 : 内存不足时 ,...回收内存 ; ⑦ 回收处理 二、硬件设备内存管理 ---- 硬件设备内存管理 : ① CPU 处理器 中的 " 内存管理单元 " ( MMU ) 和 高速缓存 ; ② 物理内存 在 " 内存管理单元

1.4K40

Linux 内核 内存管理】伙伴分配器 ① ( 伙伴分配器引入 | 块、阶 | 伙伴 )

文章目录 一、伙伴分配器引入 二、块、阶 三、伙伴 一、伙伴分配器引入 ---- Linux 内核 初始化 完成之后 , 就会 丢弃 引导内存分配器 , 如 : bootmem 分配器 , memblock...分配器 ; 此时 , 使用 " 分配器 “ 管理 ” 物理 " , " 伙伴分配器 “ 就是 ” 分配器 " , 其特点是 算法简单 , 性能高效 ; 二、块、阶 ---- 伙伴分配器 有如下概念...n 个 连续的 " 物理 " ; 如 : 0 阶块是 2^0 = 1 个 连续的 " 物理 " ; 1 阶块是 2^1 = 2 个 连续的 " 物理 " ; 2 阶块是 2...1 个物理 页号 是 2^n 的整数倍 ; ③ 合并块 : 如果需要合并这两个 n 阶块为 n + 1 阶块 , 则第 1 的 物理 页号必须是 2^{n + 1}...整数倍 ; 0 与 1 是伙伴 ; 2 与 3 是伙伴 ; 1 与 2 不是伙伴 , 这两如果合并成块 , 其第一的页号不是 2^{n + 1} 整数倍

95520

Linux 内核 内存管理】伙伴分配器 ② ( 伙伴分配分配内存流程 )

文章目录 一、伙伴分配分配内存流程 1、查询 n 阶块 2、查询 n + 1 阶块 3、查询 n + 2 阶块 一、伙伴分配分配内存流程 ---- 伙伴分配器 以 " 阶 " 为单位 , 分配.../ 释放 物理 ; 阶 ( Order ) : 物理 的 数量单位 , n 阶块 指的是 2^n 个 连续的 " 物理 " ; / 阶 概念参考 【Linux 内核 内存管理...】伙伴分配器 ① ( 伙伴分配器引入 | 块、阶 | 伙伴 ) 博客 ; " 伙伴分配器 " 分配内存流程 : 假设要 分配 n 阶块 ; 1、查询 n 阶块 查询当前是否有 空闲的 n...阶块 , 如果有则 直接分配 , 如果没有 , 则进入下一步 , 查询 n + 1 阶块 ; 2、查询 n + 1 阶块 查询当前是否有 空闲的 n + 1 阶块 , 如果有 , 将...n + 1 阶块 分成 2 个 n 阶块 , 一块插入 空闲 n 阶块链表 ; 一块 直接分配 , 如果没有 , 则进入下一步 , 查询 n + 2 阶块 ; 3、查询

7K50

Linux 内核 内存管理】Linux 内核内存布局 ③ ( Linux 内核 动态分配内存 系统接口函数 | 统计输出 vmalloc 分配内存 )

文章目录 一、Linux 内核 动态分配内存 系统接口函数 二、统计输出 vmalloc 分配内存 一、Linux 内核 动态分配内存 系统接口函数 ---- Linux 内核 " 动态分配内存 "...是通过 " 系统接口 " 实现的 , 下面介绍几个重要的 接口函数 ; ① 以 " " 为单位分配内存 : alloc_pages , __get_free_page ; ② 以 " 字节 " 为单位分配..." 虚拟地址连续的内存块 " : vmalloc ; ③ 以 " 字节 " 为单位分配 " 物理地址连续的内存块 " : kmalloc ; 注意 该 " 物理地址连续的内存块 " 是以 Slab 为中心的...; 二、统计输出 vmalloc 分配内存 ---- 执行 grep vmalloc /proc/vmallocinfo 命令 , 可以统计输出 通过 vmalloc 函数分配的 " 虚拟地址连续的内存

5.1K30

Linux 内核 内存管理】物理分配页 ⑧ ( __alloc_pages_slowpath 慢速路径调用函数源码分析 | 获取首选内存区域 | 异步回收内存 | 最低水线也分配 | 直接分配 )

文章目录 一、获取首选内存区域 二、异步回收内存 三、最低水线也分配 四、直接分配内存 在 【Linux 内核 内存管理】物理分配页 ② ( __alloc_pages_nodemask 函数参数分析..." 分配失败 , 则执行 " 慢速路径 " 分配 ; 上述涉及到了 " 快速路径 " 和 " 慢速路径 " 2 种物理分配方式 ; 继续接着上一篇博客 【Linux 内核 内存管理】物理分配页 ⑦...ac->preferred_zoneref->zone) goto nopage; 源码路径 : linux-4.12\mm\page_alloc.c#3731 二、异步回收内存 ---- 调用...wake_all_kswapds 函数 , 异步 回收 物理内存 , 这里的异步 是通过 唤醒 " 回收线程 " 进行回收内存的 ; if (gfp_mask & __GFP_KSWAPD_RECLAIM...-4.12\mm\page_alloc.c#3743 四、直接分配内存 ---- 申请 物理 内存 的阶数 , 满足以下 3 个条件 : can_direct_reclaim (costly_order

1.4K20

linux内核的冷热分配

linux本来有伙伴系统分配内存,为了加快单个内存分配linux在每个node里为每个cpu分配了一个per_cpu_pageset(暂且叫他缓存吧)。...每个缓存包含一个冷缓存和一个热缓存。这两个用法有什么区别呢。 如果申请完一个内存就立刻用来写数据,用热缓存。 如果申请完暂时用不到或者给DMA用,用冷缓存。...这主要是因为内核用free_pages释放单个内存的时候会调用free_hot_page。...刚释放的内存大概率还在cpu的cache里,也就是说热缓存里的很可能还在cpu的cache里,所以申请热缓存并且立即使用会直接访问cpu的cache速度会比较快。...其他情况就用冷缓存,冷缓存里的在主内存里,需要重新加载到cpu的cache,速度会慢一些。

94910

Linux 内存分配流程及 kmalloc 解析

手把手教你分析 Linux 启动流程 上一次咱们分析了 Linux 的启动流程和初始化流程,今天主要分析一下内存方面的初始化和常见的内存分配方式。...伙伴系统解决外部碎片问题,slab 分配器解决内部碎片问题。 1、伙伴系统基于分配,一次分配,这样就不会出现夹在中间的小内存。...3、其实所有的分配方式最底层都是伙伴系统,它先分配好一段大的内存,然后 slab 再从其中分配小的内存。...2、有的人可能知道 Linux 有一个 bootmem 分配器,这个是在Linux初始化过程中的一个临时分配器,他会在 setup_arch 函数中初始化,然后在 mm_init 中关掉,只是在伙伴系统出现之前的临时使用...回复【pdf】即可获得博主总结的上百嵌入式笔试面试题目精选汇总。 我创建了知识星球,欢迎大家扫码加入。在知识星球中有问必答。

2.5K10

Linux内存管理 - slab分配

Linux内存管理是一个非常复杂的子系统,要完全说清的话估计要一本书的篇幅。但Linux内存管理可以划分成多个部分来阐述,这篇文章主要介绍slab算法。...Linux有个叫伙伴系统的分配算法,这个算法主要解决分配连续个内存的问题。...伙伴分配算法主要以内存(4KB)作为分配单位,就是说伙伴分配算法每次可以分配 2order 个内存(order为0、1、2...9)。...但有时候我们只需要申请一个很小的内存区(如32字节),这时候使用伙伴分配算法就显得浪费了。为了解决小内存分配问题,Linux使用了slab分配算法。...:部分分配的slab slab_free:没有被分配过的slab objsize:存储的对象大小 num:一个slab能够存储的对象个数 gfporder:一个slab由2gfporder个内存组成

2.3K51

Linux申请大内存(mmap)

---- 1.为什么要使用大内存   了解操作系统内存管理的人一般都知道操作系统对内存采用多级表和分页进行管理,操作系统每个默认大小为4KB。...如果进程使用的内存过大,比如1GB,这样会在表中占用 1GB / 4KB = 262144个表项,而系统TLB可以容纳的表项远小于这个数量。...操作系统默认支持的大是2MB,当使用1GB内存时,在表中将占用 1GB / 2MB = 512个表项,可以大大提升TLB命中率,进而提升应用性能。...---- 2.怎样使用大内存 2.1 先预留一定量的大内存 #先查看系统有多少已经预留的大内存 # cat /proc/meminfo |grep -i huge #预留192个大 # sysctl...\n"); getchar(); munmap(m, s); return 0; } ---- 3.最后的话 大内存的好处不仅是减少TLB未命中次数,而且大内存分配的是物理内存,不会被操作系统的内存管理换出到磁盘上

11.4K110

Linux 内核 内存管理】内存管理系统调用 ③ ( mmap 创建内存映射原理 | 分配虚拟内存 | 物理地址与虚拟地址进行映射 | 并分配物理内存 | mmap 库函数与内核系统调用函数 )

文章目录 一、mmap 创建内存映射原理 ( 分配虚拟内存 | 物理地址与虚拟地址进行映射 | 产生缺页异常并分配物理内存 ) 1、分配虚拟内存 2、物理地址与虚拟地址进行映射 3、产生缺页异常并分配物理内存...二、mmap 库函数与 mmap 内核系统调用函数 一、mmap 创建内存映射原理 ( 分配虚拟内存 | 物理地址与虚拟地址进行映射 | 产生缺页异常并分配物理内存 ) ---- 1、分配虚拟内存...分配 虚拟内存 : 应用进程 调用 mmap 函数后 , 在 Linux 系统中 创建 " 内存映射 “ 时 , 会在 ” 用户虚拟地址空间 “ 中 , 分配一块 ” 虚拟内存区域 " ; 此处调用的...*filp, struct vm_area_struct *vma) 3、产生缺页异常并分配物理内存 缺页异常 : Linux 内核在分配 " 物理内存 “ 时 , 采用了 ” 延迟策略 “ , 即进程第一次访问...会 分配 " 物理内存 “ , 并且将 要映射的文件 的 部分数据 读取到 该 ” 物理内存 " 中 ; 匿名映射 : 对于 " 匿名映射 " , 直接分配 " 物理内存 “ , 并且在 "

2.2K10

笔记 Lab5: Lazy Page Allocation | 内存分配

实现一个内存分配机制,在调用 sbrk() 的时候,不立即分配内存,而是只作记录。在访问到这一部分内存的时候才进行实际的物理内存分配。...,就为其分配物理内存,并在表建立映射: // kernel/trap.c // // handle an interrupt, exception, or system call from user...uvmlazytouch(va); // 分配物理内存,并在表创建映射 } else { // 如果不是缺页异常,或者是在非懒加载地址上发生缺页异常,则抛出错误并杀死进程...懒分配内存在被 touch 后就可以被使用了。...懒分配不应该给这个地址分配物理和建立映射,而应该直接抛出异常) (解决 usertests 中的 stacktest 失败的问题) 表项不存在 // kernel/vm.c // touch a

71820

Linux分区分配器之水位

我们讲分配器的时候讲到了快速分配和慢速分配,其中伙伴算法是在快速分配里做的,忘记的小伙伴我们再看下: static struct page * get_page_from_freelist(gfp_t...但安卓这种大量用户操作网络接收的系统中,难免会遇到数据量突然增大,需要临时申请大量的内存,此时有可能kswapd回收的内存速度小于内存分配的速度,即发生direct reclaim,从而阻塞应用严重影响性能...我们知道在内存分配时,只有low和min之间的区域才是kswapd活动的区域。而linux中默认的low与min之间的值又比较小,所以就很容易造成direct reclaim的情况。...「watermark_scale_factor」: 内核总是在进步的,在linux内核4.6版本中,又诞生了一种新的调节水位的方式,即watermark_scale_factor系数,其默认值是10,对应内存占比...至此,分配器中的快速分配方式已经结束,下一篇让我们进入分配器的慢速分配方式:__alloc_pages_slowpath,涉及到内存碎片的整理和内存回收。

1.2K30

kmalloc分配物理内存与高端内存映射--Linux内存管理(十八)

永久内存映射区 该区域可访问高端内存. 访问方法是使用alloc_page(_GFP_HIGHMEM)分配高端内存或者使用kmap函数将分配到的高端内存映射到该区域....v=4.7, line 3853 3 分配掩码(gfp_mask标志) 3.1 分配掩码 前述所有函数中强制使用的mask参数,到底是什么语义? 我们知道Linux内存划分为内存域....如果有可能的话, 在内存管理子系统之外, 总是把下列分组之一用于内存分配. 在内核源代码中, 双下划线通常用于内部数据和定义. 而这些预定义的分组名没有双下划线前缀, 点从侧面验证了上述说法....二者的失败不会立即威胁系统稳定性, GFP_KERNEL绝对是内核源代码中最常使用的标志 最后内核设置了碎片管理的可移动依据组织的MASK信息GFP_MOVABLE_MASK, 参见include/linux...那么内存分配可以从该内存域或更低的内存域进行, 该函数定义在include/linux/gfp.h?

6.3K21

alloc_page分配内存空间--Linux内存管理(十七)

Linux内核使用二进制伙伴算法来管理和分配物理内存页面, 该算法由Knowlton设计, 后来Knuth又进行了更深刻的描述....相反, 必须指定的是分配阶, 伙伴系统将在内存分配2^0 rder 内核中细粒度的分配只能借助于slab分配器(或者slub、slob分配器), 后者基于伙伴系统 内存分配函数 功能 定义 alloc_pages...(mask, order) 分配2^0 rder 并返回一个struct page的实例,表示分配内存块的起始 NUMA-include/linux/gfp.h, line 466 UMA-include...v=4.7, line 483 get_zeroed_page(mask) 分配并返回一个page实例,对应的内存填充0(所有其他函数,分配之后的内容是未定义的) mm/page_alloc.c...如果可用内存足够,则必要的工作会很快完成,就像下述代码 4.1 函数源代码注释 __alloc_pages_nodemask函数定义在include/linux/gfp.h?v=4.7#L428

2.9K11
领券