0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Linux内存方面的初始化和常见的内存分配方式

麦辣鸡腿堡 来源:嵌入式Linux系统开发 作者:Jasonangel 2023-09-28 16:13 次阅读

在 start_kernel 内核初始化函数中,一共调用 86 个函数去初始化,其中有一个 mm_init 函数,用以初始化内存。

start_kernel
    |--- >mm_init
        |--- >mem_init

linux4.14/init/main.c

图片

在 mem_init 函数中会初始化伙伴系统和 slab 分配器。

先说两个概念:

外部碎片 :有一段小内存,夹在两个大内存中间,两个大内存已经被分配给进程,这一段小内存由于过小,不够申请者使用,就一直空闲。

内部碎片 :一个进程申请了一段内存,可是这个进程从来没有全部使用,一直有最后的一段内存没有使用。

为了解决这两个问题,就出现了伙伴系统和 slab 分配器。伙伴系统解决外部碎片问题,slab 分配器解决内部碎片问题。

1、伙伴系统基于页分配,一次分配多页,这样就不会出现夹在中间的小内存。

2、slab 分配器基于字节来分配,特别适用于需要频繁分配几十个字节的结构体,我们经常使用的 kmalloc 就是基于 slab 分配器。

3、其实所有的分配方式最底层都是伙伴系统,它先分配好一段大的内存,然后 slab 再从其中分配小的内存。

图片

这里列出了常见的内存分配 API 接口

其中最常用的就是 malloc 和 kmalloc,区别在于一个在用户空间,一个在内核空间,并且 kmalloc 的使用需要注意竞争,需要指明 flag 。

void *kmalloc(size_t size, int flags);

内核编程(驱动编程)一定要注意竞争问题,重要的数据或者内存使用前后一定要加锁。

在 kmalloc 的使用过程中,常用标志位:GFP_KERNEL、GFP_ATOMIC、GFP_USER、GFP_HIGHUSER、GFP_NOIO、GFP_NOFS。

前两个最常用,GFP_KERNEL 代表在使用 kmalloc 分配内存时,如果内存准备不足,会等待,也就是会睡眠。GFP_ATOMIC 代表使用 kmalloc 分配内存时,如果内存准备不足,会立刻返回,不会引起睡眠,适合在中断上下文或者进程上下文中使用。

补充:

1、基于 slab 分配器,出现了 slob 和 slub 分配器。在多核大系统大内存中,一般使用 slub 分配器,在极小的嵌入式系统中,一般使用 slob 分配器(只有600多行代码)。

2、有的人可能知道 Linux 有一个 bootmem 分配器,这个是在Linux初始化过程中的一个临时分配器,他会在 setup_arch 函数中初始化,然后在 mm_init 中关掉,只是在伙伴系统出现之前的临时使用。

bootmem 分配器按块进行分配,颗粒度很大,不够精细,比较浪费内存。bootmem 分配器只会在 start_kernel 函数和mm_init 函数之前存在,中间的函数会调用它进行内存分配。

start_kernel
    |--- >setup_arch
        |--- >paging_init
            |--- >bootmem_init
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 嵌入式
    +关注

    关注

    4983

    文章

    18291

    浏览量

    288540
  • 内核
    +关注

    关注

    3

    文章

    1309

    浏览量

    39862
  • Linux
    +关注

    关注

    87

    文章

    10991

    浏览量

    206742
  • 内存
    +关注

    关注

    8

    文章

    2767

    浏览量

    72777
  • 分配器
    +关注

    关注

    0

    文章

    176

    浏览量

    25296
收藏 人收藏

    评论

    相关推荐

    Linux应用开发之内存分配

    堆是长度可变的连续虚拟内存,始于进程未初始化数据段的末尾,将堆当前的内存边界称为 "program break"。
    发表于 05-08 11:17 430次阅读
    <b class='flag-5'>Linux</b>应用开发之<b class='flag-5'>内存</b><b class='flag-5'>分配</b>

    Linux内存系统: Linux 内存分配算法

    · 减少伙伴算法在分配小块连续内存时所产生的内部碎片· 将频繁使用的对象缓存起来,减少分配初始化和释放对象的时间开销· 通过着色技术调整对象以更好的使用硬件高速缓存7、slab
    发表于 08-24 07:44

    Linux内存系统:内存使用场景

    )· DMA 内存2、用户态内存分配函数· alloca 是向栈申请内存,因此无需释放· malloc 所分配
    发表于 08-25 07:42

    鸿蒙内核源码分析(内存分配篇):内存分配方式有哪些

    详细的描述,这里结合代码说。Huawei LiteOS的内存管理分为静态内存管理和动态内存管理,提供内存初始化
    发表于 11-20 10:07

    鸿蒙内核源码分析(内存分配篇):内存分配方式有哪些

    ; 开发指南> 内核开发指南> 内存> 概述 看,有更详细的描述,这里结合代码说。Huawei LiteOS的内存管理分为静态内存管理和动态内存管理,提供
    发表于 11-20 17:34

    嵌入式系统内存分配方式是怎样的

    一篇讲透嵌入式系统内存分配方式
    发表于 12-17 07:40

    内存管理程序结构

    数据区未初始化的全局,静态数据初始化的全局,静态数据代码区内存分配方式静态分配代码区数据区动态分配
    发表于 12-17 07:15

    一文解析Linux系统保留内存初始化流程

    1、Linux系统保留内存初始化流程在启动过程中会打印出如下信息,这些信息为linux呈现出系统下的保留内存空间。本文只介绍基本的保留
    发表于 06-30 16:27

    用rt_memheap_init分配内存初始化失败是何原因?怎么解决?

    用rt_memheap_init分配内存,一到初始化任务分配内存的时候就会出现问题请教一下是什么原因导致这种情况
    发表于 02-13 14:18

    Linux内存初始化

    之前有几篇博客详细介绍了Xen的内存初始化,确实感觉这部分内容蛮复杂的。这两天在看Linux内核启动中内存初始化,也是看的云里雾里的,想尝
    发表于 10-12 11:16 0次下载

    解析内核初始化时根内存盘的加载过程

    2006-12-12 13:54:41 来源:Linux 宝库 分享到:标签:loadlin gzip 作者:opera 概述 ==== 1)当内核配置了内存盘时, 内核在初始化时可以将软盘加载
    发表于 11-08 10:40 0次下载

    浅谈内存分配方式 避免内存浪费问题

    说到内存分配方式,就不得不提连续分配方式。这种方式是指为一个用户程序分配一个连续的内存空间,它
    发表于 03-03 11:22 1274次阅读

    什么是堆内存?堆内存是如何分配的?

    在一般的编译系统中,堆内存分配方向和栈内存是相反的。当栈内存从高地址向低地址增长的时候,堆内存从低地址向高地址
    的头像 发表于 07-05 17:58 9527次阅读

    heap_1内存分配方

    heap_1 内存分配方法 动 态 内 存 分 配 需 要 一 个 内 存 堆 , FreeRTOS 中 的 内 存 堆 为 ucHeap
    的头像 发表于 07-30 10:33 378次阅读

    heap_2内存的特性与分配方

    heap_2 内存分配方法 heap_2 提供了一个更好的分配算法,不像 heap_1那样,heap_2 提供了内存释放函数。heap_2 不会把释放的
    的头像 发表于 07-30 10:36 375次阅读