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

相关文章

Java JAR 启动内存参数配置指南(从基础设置到性能优化)

《JavaJAR启动内存参数配置指南(从基础设置到性能优化)》在启动Java可执行JAR文件时,合理配置JVM内存参数是保障应用稳定性和性能的关键,本文将系统讲解如何通过命令行参数、环境变量等方式... 目录一、核心内存参数详解1.1 堆内存配置1.2 元空间配置(MetASPace)1.3 线程栈配置1.

Elasticsearch 的索引管理与映射配置实战指南

《Elasticsearch的索引管理与映射配置实战指南》在本文中,我们深入探讨了Elasticsearch中索引与映射的基本概念及其重要性,通过详细的操作示例,我们了解了如何创建、更新和删除索引,... 目录一、索引操作(一)创建索引(二)删除索引(三)关闭索引(四)打开索引(五)索引别名二、映射操作(一

深入理解Mysql OnlineDDL的算法

《深入理解MysqlOnlineDDL的算法》本文主要介绍了讲解MysqlOnlineDDL的算法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小... 目录一、Online DDL 是什么?二、Online DDL 的三种主要算法2.1COPY(复制法)

Linux创建服务使用systemctl管理详解

《Linux创建服务使用systemctl管理详解》文章指导在Linux中创建systemd服务,设置文件权限为所有者读写、其他只读,重新加载配置,启动服务并检查状态,确保服务正常运行,关键步骤包括权... 目录创建服务 /usr/lib/systemd/system/设置服务文件权限:所有者读写js,其他

Python内存管理机制之垃圾回收与引用计数操作全过程

《Python内存管理机制之垃圾回收与引用计数操作全过程》SQLAlchemy是Python中最流行的ORM(对象关系映射)框架之一,它提供了高效且灵活的数据库操作方式,本文将介绍如何使用SQLAlc... 目录安装核心概念连接数据库定义数据模型创建数据库表基本CRUD操作创建数据读取数据更新数据删除数据查

在Node.js中使用.env文件管理环境变量的全过程

《在Node.js中使用.env文件管理环境变量的全过程》Node.js应用程序通常依赖于环境变量来管理敏感信息或配置设置,.env文件已经成为一种流行的本地管理这些变量的方法,本文将探讨.env文件... 目录引言为什么使php用 .env 文件 ?如何在 Node.js 中使用 .env 文件最佳实践引

python库pydantic数据验证和设置管理库的用途

《python库pydantic数据验证和设置管理库的用途》pydantic是一个用于数据验证和设置管理的Python库,它主要利用Python类型注解来定义数据模型的结构和验证规则,本文给大家介绍p... 目录主要特点和用途:Field数值验证参数总结pydantic 是一个让你能够 confidentl

k8s容器放开锁内存限制问题

《k8s容器放开锁内存限制问题》nccl-test容器运行mpirun时因NCCL_BUFFSIZE过大导致OOM,需通过修改docker服务配置文件,将LimitMEMLOCK设为infinity并... 目录问题问题确认放开容器max locked memory限制总结参考:https://Access

SpringBoot 多环境开发实战(从配置、管理与控制)

《SpringBoot多环境开发实战(从配置、管理与控制)》本文详解SpringBoot多环境配置,涵盖单文件YAML、多文件模式、MavenProfile分组及激活策略,通过优先级控制灵活切换环境... 目录一、多环境开发基础(单文件 YAML 版)(一)配置原理与优势(二)实操示例二、多环境开发多文件版

Redis实现高效内存管理的示例代码

《Redis实现高效内存管理的示例代码》Redis内存管理是其核心功能之一,为了高效地利用内存,Redis采用了多种技术和策略,如优化的数据结构、内存分配策略、内存回收、数据压缩等,下面就来详细的介绍... 目录1. 内存分配策略jemalloc 的使用2. 数据压缩和编码ziplist示例代码3. 优化的