LiteOS内存管理:TLSF算法

2023-12-02 11:28
文章标签 算法 内存 管理 liteos tlsf

本文主要是介绍LiteOS内存管理:TLSF算法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

问题背景

TLSF算法主要是面向实时操作系统提出的,对于RTOS而言,执行时间的确定性是最根本的,然而传统的动态内存分配器(DMA,Dynamic Memory Allocator)存在两个主要问题:

  1. 最坏情况执行时间不确定(not bounded)或者复杂度过高。
  2. 碎片化问题。

TLSF的提出,较好地解决了以上两个问题:将动态内存的分配与回收时间复杂度都降到了O(1)时间复杂度,并且采用了Good-fit的分配策略保证系统运行时不会产生过多碎片。

TLSF概要

TLSF(Two-Level Segregated Fit),从命名来看主要分为三部分:

  1. Segregated Free List
  2. Two-Level Bitmap
  3. Good Fit

前两个是数据结构,第三个是分配策略。
TLSF主要采用两级位图(Two-Level Bitmap)与分级空闲块链表(Segregated Free List)的数据结构管理动态内存池(memory pool)以及其中的空闲块(free blocks),用Good-Fit的策略进行分配。

隔离空闲链表

将Segregated Free List拆开,分为:

  1. List:隐式链表,管理所有内存块。
  2. Free List:显示链表,只管理空闲块。
  3. Segregated Free List:隔离空闲块链表,按空闲块大小分级,用多个链表管理。

List
链表是内存管理中最常见的数据结构,在一块内存块头部添加一个头结点,记录该Block本身的信息,以及前后级Block的关系。

在这里插入图片描述
隐式链表,链接所有内存块,只记录内存块大小,由于内存块相连,通过头结点指针加内存块大小即可得到下一个内存块的位置。
没有显示指明内存块的地址,而是通过计算得到,所以又叫做隐式链表。

当需要分配内存时,需要从第一块内存块开始检索,检查该内存块是否被分配以及内存块大小是否满足需要,直到找到大小合适的空闲块分配出去。

隐式链表主要问题在于当内存分配时并不需要检索已分配的内存块,这浪费了不少时间,只需要检索空闲块即可。

因此,显示空闲块链表在空闲块头部添加一个指针域,指向下一个空闲块,这样检索时会跳过已分配的内存块(used blocks)。

在这里插入图片描述
Segregated Free List
在这里插入图片描述
隐式链表和显示链表主要问题在于当空闲块个数为n时,检索复杂度在O(n)级别,速度较慢,分级空闲块链表优化了空闲块检索的复杂度,粗略计算大概降到O(log n)级别。

分级空闲块链表(Segregated Free List)的设计思想是将空闲块按照大小分级,形成了不同块大小范围的分级(class),组内空闲块用链表链接起来。
每次分配时先按分级大小范围查找到相应链表,再从相应链表挨个检索合适的空闲块,如果找不到,就在大小范围更大的一级查找,直到找到合适的块分配出去。

Two-Level Bitmap

上面我们介绍了分级空闲块链表的原理,但是我们并没有提及如何按照空闲块大小分级。
TLSF算法引入了位图(bitmap)来解决这个问题。

位图(Bitmap)

  1. 节省存储空间:用1-bit表示某个区间范围大小的空闲块是否存在。
  2. 位操作速度快:部分体系结构有加速特殊位操作的指令(如clz,ffs,fls)。

SEgregated List + Two-Level Bitmap

在这里插入图片描述
TLSF采用了两级位图(Two-Level Bitmap)来管理不同大小范围的空闲块链(free block lists)。上图中包含三个虚线矩形框分别是:

  1. 第一级位图,表示内存块的粗粒度范围,一般是2的幂次粒度。
  2. 第二级位图,表示内存块的细粒度范围。
  3. 第三个框是内存中真正的空闲内存块(free blocks)。

内存分配与释放流程(简版)

有了TLSF的大体框架概念以后,就可以先看一下内存alloc与free的简要流程。

内存分配流程

  1. 在位图中搜索合适的空闲块大小范围,找到free list的头指针。
  2. 基于free list的头指针检索list分配空闲块。

内存释放流程

  1. 将需要释放的内存块置为空闲块。
  2. 与该空闲块物理上相邻的空闲块合并。
  3. 计算合并后的空闲块大小范围,检索位图找到对应的free list。
  4. 将该内存块加入free list,返回给内存池。

Good-fit

常规思路:Best-fit(内部碎片最优)
在这里插入图片描述
常规思路是:找到能满足内存请求大小的最小空闲块,就会有下面的流程(以搜索大小为69字节的空闲块为例)。

  1. 基于位运算找到请求大小所在的第一级位图(First-Level bitmap)对应的粗粒度范围([ 64 ~ 128 ]),也就是二级位图的索引
  2. 在粗粒度范围内,根据二级位图索引检索第二级位图(Second-Level bitmap)得到细粒度范围([ 68 ~ 70 ])
  3. 如上图所示,沿着右下角空闲块链表可以检索到69字节的那一块是Best-fit

Best-fit已经很不错了,但仍然有提升空间。Best-fit策略最主要的问题还在于第三步,仍然需要检索对应范围的那一条空闲块链表,存在潜在的时间复杂度。

Good-fit(少量碎片换取O(1)时间复杂度)
Good-fit并不保证找到满足需求的最小空闲块,而是尽可能接近要分配的大小。

还以上述搜索大小为69字节的空闲块为例,查找范围稍微大一点儿的,如[70,72],这样设计的好处是[70,72]对应的空闲块链中每一块都能满足需求,不需要检索空闲块链表找到最小的,而是直接取空闲块链中第一块即可。整体上也不会造成太多碎片。

这篇关于LiteOS内存管理:TLSF算法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/445157

相关文章

C++高效内存池实现减少动态分配开销的解决方案

《C++高效内存池实现减少动态分配开销的解决方案》C++动态内存分配存在系统调用开销、碎片化和锁竞争等性能问题,内存池通过预分配、分块管理和缓存复用解决这些问题,下面就来了解一下... 目录一、C++内存分配的性能挑战二、内存池技术的核心原理三、主流内存池实现:TCMalloc与Jemalloc1. TCM

使用jenv工具管理多个JDK版本的方法步骤

《使用jenv工具管理多个JDK版本的方法步骤》jenv是一个开源的Java环境管理工具,旨在帮助开发者在同一台机器上轻松管理和切换多个Java版本,:本文主要介绍使用jenv工具管理多个JD... 目录一、jenv到底是干啥的?二、jenv的核心功能(一)管理多个Java版本(二)支持插件扩展(三)环境隔

Redis过期删除机制与内存淘汰策略的解析指南

《Redis过期删除机制与内存淘汰策略的解析指南》在使用Redis构建缓存系统时,很多开发者只设置了EXPIRE但却忽略了背后Redis的过期删除机制与内存淘汰策略,下面小编就来和大家详细介绍一下... 目录1、简述2、Redis http://www.chinasem.cn的过期删除策略(Key Expir

Python中bisect_left 函数实现高效插入与有序列表管理

《Python中bisect_left函数实现高效插入与有序列表管理》Python的bisect_left函数通过二分查找高效定位有序列表插入位置,与bisect_right的区别在于处理重复元素时... 目录一、bisect_left 基本介绍1.1 函数定义1.2 核心功能二、bisect_left 与

Spring中管理bean对象的方式(专业级说明)

《Spring中管理bean对象的方式(专业级说明)》在Spring框架中,Bean的管理是核心功能,主要通过IoC(控制反转)容器实现,下面给大家介绍Spring中管理bean对象的方式,感兴趣的朋... 目录1.Bean的声明与注册1.1 基于XML配置1.2 基于注解(主流方式)1.3 基于Java

基于Python+PyQt5打造一个跨平台Emoji表情管理神器

《基于Python+PyQt5打造一个跨平台Emoji表情管理神器》在当今数字化社交时代,Emoji已成为全球通用的视觉语言,本文主要为大家详细介绍了如何使用Python和PyQt5开发一个功能全面的... 目录概述功能特性1. 全量Emoji集合2. 智能搜索系统3. 高效交互设计4. 现代化UI展示效果

Mysql中的用户管理实践

《Mysql中的用户管理实践》:本文主要介绍Mysql中的用户管理实践,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录13. 用户管理13.1 用户 13.1.1 用户信息 13.1.2 创建用户 13.1.3 删除用户 13.1.4 修改用户

Java内存区域与内存溢出异常的详细探讨

《Java内存区域与内存溢出异常的详细探讨》:本文主要介绍Java内存区域与内存溢出异常的相关资料,分析异常原因并提供解决策略,如参数调整、代码优化等,帮助开发者排查内存问题,需要的朋友可以参考下... 目录一、引言二、Java 运行时数据区域(一)程序计数器(二)Java 虚拟机栈(三)本地方法栈(四)J

linux服务之NIS账户管理服务方式

《linux服务之NIS账户管理服务方式》:本文主要介绍linux服务之NIS账户管理服务方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、所需要的软件二、服务器配置1、安装 NIS 服务2、设定 NIS 的域名 (NIS domain name)3、修改主

使用雪花算法产生id导致前端精度缺失问题解决方案

《使用雪花算法产生id导致前端精度缺失问题解决方案》雪花算法由Twitter提出,设计目的是生成唯一的、递增的ID,下面:本文主要介绍使用雪花算法产生id导致前端精度缺失问题的解决方案,文中通过代... 目录一、问题根源二、解决方案1. 全局配置Jackson序列化规则2. 实体类必须使用Long封装类3.