电子说
内存使用场景
out of memory 的时代过去了吗?no,内存再充足也不可任性使用。
1、内存的使用场景
page 管理
slab(kmalloc、内存池)
用户态内存使用(malloc、relloc 文件映射、共享内存)
程序的内存 map(栈、堆、code、data)
内核和用户态的数据传递(copy_from_user、copy_to_user)
内存映射(硬件寄存器、保留内存)
DMA 内存
2、用户态内存分配函数
alloca 是向栈申请内存,因此无需释放
malloc 所分配的内存空间未被初始化,使用 malloc() 函数的程序开始时(内存空间还没有被重新分配) 能正常运行,但经过一段时间后(内存空间已被重新分配) 可能会出现问题
calloc 会将所分配的内存空间中的每一位都初始化为零
realloc 扩展现有内存空间大小
a) 如果当前连续内存块足够 realloc 的话,只是将 p 所指向的空间扩大,并返回 p 的指针地址。这个时候 q 和 p 指向的地址是一样的
b) 如果当前连续内存块不够长度,再找一个足够长的地方,分配一块新的内存,q,并将 p 指向的内容 copy 到 q,返回 q。并将 p 所指向的内存空间删除
3、内核态内存分配函数
函数分配原理最大内存其他_get_free_pages直接对页框进行操作4MB适用于分配较大量的连续物理内存kmem_cache_alloc基于 slab 机制实现128KB适合需要频繁申请释放相同大小内存块时使用kmalloc基于 kmem_cache_alloc 实现128KB最常见的分配方式,需要小于页框大小的内存时可以使用vmalloc建立非连续物理内存到虚拟地址的映射物理不连续,适合需要大内存,但是对地址连续性没有要求的场合dma_alloc_coherent基于_alloc_pages 实现4MB适用于 DMA 操作ioremap实现已知物理地址到虚拟地址的映射适用于物理地址已知的场合,如设备驱动alloc_bootmem在启动 kernel 时,预留一段内存,内核看不见小于物理内存大小,内存管理要求较高
4、malloc 申请内存
调用 malloc 函数时,它沿 free_chuck_list 连接表寻找一个大到足以满足用户请求所需要的内存块
free_chuck_list 连接表的主要工作是维护一个空闲的堆空间缓冲区链表
如果空间缓冲区链表没有找到对应的节点,需要通过系统调用 sys_brk 延伸进程的栈空间
5、缺页异常
通过 get_free_pages 申请一个或多个物理页面
换算 addr 在进程 pdg 映射中所在的 pte 地址
将 addr 对应的 pte 设置为物理页面的首地址
系统调用:Brk—申请内存小于等于 128kb,do_map—申请内存大于 128kb
6、用户进程访问内存分析
用户态进程独占虚拟地址空间,两个进程的虚拟地址可相同
在访问用户态虚拟地址空间时,如果没有映射物理地址,通过系统调用发出缺页异常
缺页异常陷入内核,分配物理地址空间,与用户态虚拟地址建立映射
7、共享内存
1) 原理
它允许多个不相关的进程去访问同一部分逻辑内存
两个运行中的进程之间传输数据,共享内存将是一种效率极高的解决方案
两个运行中的进程共享数据,是进程间通信的高效方法,可有效减少数据拷贝的次数
2) shm 接口
shmget 创建共享内存
shmat 启动对该共享内存的访问,并把共享内存连接到当前进程的地址空间
shmdt 将共享内存从当前进程中分离
责编AJX
全部0条评论
快来发表一下你的评论吧 !