博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
OK6410A 开发板 (八) 51 linux-5.11 OK6410A glibc提供的mmap与malloc
阅读量:4285 次
发布时间:2019-05-27

本文共 2428 字,大约阅读时间需要 8 分钟。

glibc

根据 可以看到 glibc 来自于 交叉编译工具链,且glibc版本为 glibc-2.18

我们探究一下 glibc-2.18 中 mmap 以及 malloc 函数的定义以及实现glibc 代码 在 http://ftp.gnu.org/gnu/glibc/

mmap

  • 简介
mmap 是glibc提供的函数,也是系统调用
  • 应用
#include 
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);int munmap(void *addr, size_t length);mmap 函数 有个参数 flags , 可以根据 flags 将 mmap 分为四种情况 A1. 私有匿名映射 : 用于 分配大块内存(128KB及以上) fd = -1 flags=MAP_ANONYMOUS|MAP_PRIVATE A2. 共享匿名映射 : 用于 父子进程通信 fs = -1 flags=MAP_ANONYMOUS|MAP_SHARED B1. 私有文件映射 : 用于 加载动态共享库 flags >=0 flags=MAP_PRIVATE B2. 共享文件映射 : 用于 读写文件/进程间通信 flags >=0 flags=MAP_SHARED可以这么讲,mmap就是为了读写文件存在的,读写文件流程一直在优化,在linux上,分为几个阶段 1. 直接读写磁盘 // 缺点是每次读写都要陷入内核空间,都要转动磁盘 2. 页缓存技术 // 缺点是每次读写都要陷入内核空间 3. 也缓存技术+fread/fwrite // 缺点是增加了数据在不同缓冲区复制的次数 4. mmap技术 // 优点 : 减少系统调用和内存复制的次数
  • 具体实现
glibc-2.18/ports/sysdeps/unix/sysv/linux/generic/wordsize-32/mmap.c__mmap (__ptr_t addr, size_t len, int prot, int flags, int fd, off_t offset)	return (__ptr_t) INLINE_SYSCALL (mmap2, 6, addr, len, prot, flags, fd, offset >> MMAP_PAGE_SHIFT);weak_alias (__mmap, mmap)
linux-5.11/arch/arm/include/generated/uapi/asm/unistd-common.h155 #define __NR_mmap2 (__NR_SYSCALL_BASE + 192)

malloc

  • 简介
malloc 是glibc提供的函数,不是系统调用底层封装的是 系统调用mmap 和 系统调用brk
  • 应用
用于 申请小块内存(128KB以下,不包括)
  • 实现理论
用户空间的 内存分配器为了减少系统调用带来的开销(提高内存申请效率)在 glibc 中实现了用户空间的内存分配器(ptmalloc/ptmalloc2)用户申请的内存被 ptmalloc 管理 , 每一个内存块被称为 chunk,用 malloc_chunk 表示将相同种类的 chunk 放到 链表bin中,有128个bin128个bin 被分类为	unsorted bin	fast bins	small bins	large bins但是如果 用户空间的 内存管理器 没有内存的话,还是要向内核申请内存用的是系统调用,包括两种	1. brk	2. mmap1.获取分配区的锁。  2.根据用户的需要申请的大小算出给与的大小。3.判断所需要的大小 <= max_fast,是就跳转第5步,否则下一步4.首先在fast bin 找,找不到就下一步,否则下一步5.size <= 512B ,判断是否在small bin 中,如果在就下一步,否则就第6步6.找到一个合适的chunk 大小,否则就下一步7.到了这一步,可以看到这是一个很大size了,先遍历fast bins 合并空闲块到unsorted bin 再次合并这个块里的大小,再次比对大小信息,如果可以分配就切割大小并且将剩下的部分加入到small bin 或者 large bin 中。如果依然 < SIZE 调转下一步。8.此时我们就表示我们从fast small unsorted 都找不到合适的块的大小,所以我们就到large bin 中寻找合适的大小。如果没有找到,就调转下一步了。9.走到这里基本上就是说这个块非常打了,所以我们就动用TOP chunk 改变堆的大小了,如果依然不能满足需求。调转下一步。10.这时候判断SIZE 和 mmap()分配阀值的大小。如果大于分配阀值就使用mmap()函数分配,否则调用sbrk()扩大堆的大小。
  • 具体实现
glibc-2.18/misc/sbrk.c33 __sbrk (intptr_t increment)	__brkweak_alias (__sbrk, sbrk)glibc-2.18/ports/sysdeps/unix/sysv/linux/arm/brk.c__brk (void *addr)	__curbrk = newbrk = (void *) INLINE_SYSCALL (brk, 1, addr);weak_alias (__brk, brk)
linux-5.11/arch/arm/include/generated/uapi/asm/unistd-common.h36 #define __NR_brk (__NR_SYSCALL_BASE + 45)

转载地址:http://vjigi.baihongyu.com/

你可能感兴趣的文章
cocos2d-x lua
查看>>
php protobuffer
查看>>
google play in app billing
查看>>
cakephp发送post请求
查看>>
android ant
查看>>
提取非行间样式
查看>>
基于idea+session组件+wagon实现打包部署
查看>>
shiro的总结篇
查看>>
在linux服务器上使用软连接进行启动jar包
查看>>
linux中查看磁盘是否使用沾满
查看>>
linux同一台机器安装两台nginx
查看>>
让es进行后端进程的方式启动
查看>>
es2.4.5 离线安装head插件
查看>>
实战项目经验得到的常用linux命令(-)
查看>>
Mysql的设计规范和结构优化(-)
查看>>
查看是否安装mysql以及是否正在运行的mysql
查看>>
剑指offer(39):数字在排序数组中出现的次数
查看>>
剑指offer(40):二叉树的深度
查看>>
剑指offer(41):判断二叉树是否为平衡二叉树(AVL树)
查看>>
剑指offer(42):数组中只出现1次的数字
查看>>