- 获取分配区(arena)的锁 , 以确保多线程环境下的内存分配操作不会发生冲突;
- 计算出需要分配的chunk的实际大小;
- 首先检查chunk的大小是否小于max_fast(默认64字节) , 如果是 , 则尝试从fast bins中获取适合的chunk , 如果找到则分配结束 。否则 , 继续下一步;
- 如果chunk的大小小于512字节 , 尝试从small bins中获取合适的chunk , 如果找到则分配结束 。否则 , 继续下一步;
- 如果以上步骤都未成功 , 会首先遍历fast bins中的chunk , 将相邻的chunk合并 , 并链接到unsorted bin中 , 然后遍历unsorted bins 。如果unsorted bins中只有一个chunk且大小大于待分配的chunk , 则将其切分 , 并将剩余的部分继续放入unsorted bins;如果unsorted bins中有大小适合的chunk , 则分配结束 。否则 , 继续下一步;
- 如果以上步骤都未成功 , 在large bins中查找合适的chunk , 进行切割 , 并将剩余部分放回unsorted bin 。如果fast bins和bins都没有找到合适的chunk , 那么就需要操作top chunk来进行分配了 。如果top chunk的大小比用户所请求的大小还大 , 则将top chunk切分为两部分:User chunk(用户请求大小)和Remainder chunk(剩余大小) , 并将剩余块作为新的top chunk 。如果top chunk的大小小于用户所请求的大小 , 根据分配区的类型(主分配区或非主分配区) , 通过sbrk(主分配区)或mmap(非主分配区)系统调用来扩展top chunk的大小;
- 如果以上步骤都未成功 , 根据需要的chunk大小 , 选择调用sbrk(主分配区)或mmap(非主分配区)系统调用来分配内存块;
- 使用mmap系统调用为程序的内存空间映射一块大小为chunk_size、对齐到4KB的内存空间 , 并将内存指针返回给用户;
- 判断是否为第一次调用malloc , 如果是主分配区 , 则需要进行初始化工作 , 分配一块初始大小为(chunk_size + 128KB)、对齐到4KB的空间作为初始的heap 。如果已经初始化过了 , 主分配区则调用sbrk(主分配区)来增加heap的大小 , 非主分配区则在top chunk中切割出一个chunk以满足分配需求 。
- 首先 , 获取分配区的锁 , 以确保线程安全性;
- 如果要释放的是空指针 , 则无需执行任何操作 , 直接返回;
- 检查当前的内存块(chunk)是否是通过mmap映射的内存区域 。如果是的话 , 直接通过munmap()函数将该chunk释放 。我们可以通过已使用chunk的数据结构中的"M"标志来判断是否是mmap映射的内存;
- 判断chunk是否与顶部内存块(top chunk)相邻 。如果相邻 , 将它们合并在一起(相邻意味着与分配区中的空闲chunk相邻) 。然后 , 继续下一步骤;
- 如果chunk的大小大于max_fast(64字节) , 将其放入未排序的bin中 , 并检查是否需要合并 。如果需要合并且与top chunk相邻 , 进入下一步骤;
- 如果内存块的大小小于max_fast(64字节) , 直接放入快速bin中 , 而不改变chunk的状态 。然后 , 检查是否需要合并 , 如果需要合并 , 继续下一步骤;
- 在快速bin中 , 如果当前chunk的下一个chunk也是空闲的 , 将它们合并 , 并将合并后的chunk放回未排序的bin中 。如果合并后的chunk大小大于64字节 , 将触发快速bin的合并操作 , 将与相邻的空闲chunk合并后 , 放回未排序的bin中 。如果合并后的chunk与top chunk相邻 , 将它们合并到top chunk中;
- 最后 , 检查top chunk的大小是否大于mmap的收缩阈值(默认为128KB) 。如果是 , 尝试将部分top chunk归还给操作系统 , 然后结束内存释放操作 。
推荐阅读
- 鹅怎么养殖技术 鹅怎么养殖技术视频
- 巨峰葡萄种植技术与管理 巨峰葡萄种植技术
- 枇杷树嫁接技术图解 枇杷树嫁接方法技术
- Redis Stream 数据结构实现原理真的很强
- AI生成内容归谁?百度、讯飞、商汤协议“打架”,专家称AI时代版权是技术问题
- 物联网边缘技术框架KubeEdge:基于Kubernetes构建的云原生边缘计算框架
- 十种数据库缓存相关的技术和机制
- 5G毫米波技术是否为下一阶段的连接铺平了道路?
- 电力猫原理 电力猫原理如何使用方法
- 今天来聊一聊人体三维重建技术中的时域融合驱动方法