|
STATIC INLINE UINT16 | OsMemFFS (UINT32 bitmap) |
|
STATIC INLINE UINT16 | OsMemFLS (UINT32 bitmap) |
|
STATIC INLINE UINT32 | OsMemLog2 (UINT32 size) |
|
STATIC INLINE UINT32 | OsMemFlGet (UINT32 size) |
|
STATIC INLINE UINT32 | OsMemSlGet (UINT32 size, UINT32 fl) |
|
STATIC INLINE VOID | OsMemFreeNodeAdd (VOID *pool, struct OsMemFreeNodeHead *node) |
| 添加一个空闲节点 更多...
|
|
STATIC INLINE UINT32 | OsMemFree (struct OsMemPoolHead *pool, struct OsMemNodeHead *node) |
| 释放内存 更多...
|
|
STATIC VOID | OsMemInfoPrint (VOID *pool) |
|
STATIC INLINE UINT32 | OsMemAllocCheck (struct OsMemPoolHead *pool, UINT32 intSave) |
|
STATIC INLINE VOID | OsMemNodeSetTaskID (struct OsMemUsedNodeHead *node) |
|
STATIC INLINE VOID | OsMemWaterUsedRecord (struct OsMemPoolHead *pool, UINT32 size) |
|
STATIC INLINE struct OsMemNodeHead * | OsMemLastSentinelNodeGet (const struct OsMemNodeHead *sentinelNode) |
| 更新哨兵节点内容 更多...
|
|
STATIC INLINE BOOL | OsMemSentinelNodeCheck (struct OsMemNodeHead *sentinelNode) |
| 检查哨兵节点 更多...
|
|
STATIC INLINE BOOL | OsMemIsLastSentinelNode (struct OsMemNodeHead *sentinelNode) |
| 是否为最后一个哨兵节点 更多...
|
|
STATIC INLINE VOID | OsMemSentinelNodeSet (struct OsMemNodeHead *sentinelNode, VOID *newNode, UINT32 size) |
| 设置哨兵节点内容 更多...
|
|
STATIC INLINE VOID * | OsMemSentinelNodeGet (struct OsMemNodeHead *node) |
|
STATIC INLINE struct OsMemNodeHead * | PreSentinelNodeGet (const VOID *pool, const struct OsMemNodeHead *node) |
|
UINT32 | OsMemLargeNodeFree (const VOID *ptr) |
| 大内存释放 更多...
|
|
STATIC INLINE BOOL | TryShrinkPool (const VOID *pool, const struct OsMemNodeHead *node) |
|
STATIC INLINE INT32 | OsMemPoolExpandSub (VOID *pool, UINT32 size, UINT32 intSave) |
| 内存池扩展实现 更多...
|
|
STATIC INLINE INT32 | OsMemPoolExpand (VOID *pool, UINT32 allocSize, UINT32 intSave) |
| 扩展内存池 更多...
|
|
VOID | LOS_MemExpandEnable (VOID *pool) |
| Enable memory pool to support dynamic expansion. 更多...
|
|
STATIC INLINE VOID | OsLmsFirstNodeMark (VOID *pool, struct OsMemNodeHead *node) |
|
STATIC INLINE VOID | OsLmsAllocAlignMark (VOID *ptr, VOID *alignedPtr, UINT32 size) |
|
STATIC INLINE VOID | OsLmsReallocMergeNodeMark (struct OsMemNodeHead *node) |
|
STATIC INLINE VOID | OsLmsReallocSplitNodeMark (struct OsMemNodeHead *node) |
|
STATIC INLINE VOID | OsLmsReallocResizeMark (struct OsMemNodeHead *node, UINT32 resize) |
|
STATIC INLINE VOID | OsMemLinkRegisterRecord (struct OsMemNodeHead *node) |
|
STATIC INLINE VOID | OsMemUsedNodePrint (struct OsMemNodeHead *node) |
|
VOID | OsMemUsedNodeShow (VOID *pool) |
| 打印已使用的节点 更多...
|
|
STATIC VOID | OsMemNodeBacktraceInfo (const struct OsMemNodeHead *tmpNode, const struct OsMemNodeHead *preNode) |
|
STATIC INLINE UINT32 | OsMemFreeListIndexGet (UINT32 size) |
|
STATIC INLINE struct OsMemFreeNodeHead * | OsMemFindCurSuitableBlock (struct OsMemPoolHead *poolHead, UINT32 index, UINT32 size) |
|
STATIC INLINE UINT32 | OsMemNotEmptyIndexGet (struct OsMemPoolHead *poolHead, UINT32 index) |
|
STATIC INLINE struct OsMemFreeNodeHead * | OsMemFindNextSuitableBlock (VOID *pool, UINT32 size, UINT32 *outIndex) |
| 找到下一个合适的块 更多...
|
|
STATIC INLINE VOID | OsMemSetFreeListBit (struct OsMemPoolHead *head, UINT32 index) |
|
STATIC INLINE VOID | OsMemClearFreeListBit (struct OsMemPoolHead *head, UINT32 index) |
|
STATIC INLINE VOID | OsMemListAdd (struct OsMemPoolHead *pool, UINT32 listIndex, struct OsMemFreeNodeHead *node) |
|
STATIC INLINE VOID | OsMemListDelete (struct OsMemPoolHead *pool, UINT32 listIndex, struct OsMemFreeNodeHead *node) |
| 从空闲链表中删除 更多...
|
|
STATIC INLINE VOID | OsMemFreeNodeDelete (VOID *pool, struct OsMemFreeNodeHead *node) |
| 从空闲链表上摘除节点 更多...
|
|
STATIC INLINE struct OsMemNodeHead * | OsMemFreeNodeGet (VOID *pool, UINT32 size) |
|
STATIC INLINE VOID | OsMemMergeNode (struct OsMemNodeHead *node) |
| 合并节点,和前面的节点合并 node 消失 更多...
|
|
STATIC INLINE VOID | OsMemSplitNode (VOID *pool, struct OsMemNodeHead *allocNode, UINT32 allocSize) |
| 切割节点 更多...
|
|
STATIC INLINE VOID * | OsMemCreateUsedNode (VOID *addr) |
|
STATIC UINT32 | OsMemPoolInit (VOID *pool, UINT32 size) |
| OsMemPoolInit 内存池初始化 内存池节点部分包含3种类型节点:未使用空闲内存节点(OsMemFreeNodeHead),已使用内存节点(OsMemUsedNodeHead) 和 尾节点(OsMemNodeHead)。
每个内存节点维护一个前序指针,指向内存池中上一个内存节点,还维护内存节点的大小和使用标记。
空闲内存节点和已使用内存节点后面的内存区域是数据域 更多...
|
|
STATIC VOID | OsMemPoolDeinit (VOID *pool) |
|
STATIC UINT32 | OsMemPoolAdd (VOID *pool, UINT32 size) |
| 新增内存池 更多...
|
|
STATIC UINT32 | OsMemPoolDelete (VOID *pool) |
| 删除内存池 更多...
|
|
UINT32 | LOS_MemInit (VOID *pool, UINT32 size) |
| LOS_MemInit 初始化一块指定的动态内存池,大小为size 初始一个内存池后生成一个内存池控制头、尾节点EndNode,剩余的内存被标记为FreeNode内存节点。 更多...
|
|
UINT32 | LOS_MemDeInit (VOID *pool) |
| 删除指定内存池 更多...
|
|
UINT32 | LOS_MemPoolList (VOID) |
| 打印系统中已初始化的所有内存池,包括内存池的起始地址、内存池大小、空闲内存总大小、已使用内存总大小、最大的空闲内存块大小、空闲内存块数量、已使用的内存块数量。 更多...
|
|
STATIC INLINE VOID * | OsMemAlloc (struct OsMemPoolHead *pool, UINT32 size, UINT32 intSave) |
| 从指定动态内存池中申请size长度的内存 更多...
|
|
VOID * | LOS_MemAlloc (VOID *pool, UINT32 size) |
| 从指定内存池中申请size长度的内存,注意这可不是从内核堆空间中申请内存 更多...
|
|
VOID * | LOS_MemAllocAlign (VOID *pool, UINT32 size, UINT32 boundary) |
| 从指定内存池中申请size长度的内存且地址按boundary字节对齐的内存 更多...
|
|
STATIC INLINE BOOL | OsMemAddrValidCheck (const struct OsMemPoolHead *pool, const VOID *addr) |
| 内存池有效性检查 更多...
|
|
STATIC INLINE BOOL | OsMemIsNodeValid (const struct OsMemNodeHead *node, const struct OsMemNodeHead *startNode, const struct OsMemNodeHead *endNode, const struct OsMemPoolHead *poolInfo) |
|
STATIC BOOL | MemCheckUsedNode (const struct OsMemPoolHead *pool, const struct OsMemNodeHead *node, const struct OsMemNodeHead *startNode, const struct OsMemNodeHead *endNode) |
|
STATIC UINT32 | OsMemCheckUsedNode (const struct OsMemPoolHead *pool, const struct OsMemNodeHead *node) |
|
UINT32 | LOS_MemFree (VOID *pool, VOID *ptr) |
| 释放从指定动态内存中申请的内存 更多...
|
|
STATIC INLINE VOID | OsMemReAllocSmaller (VOID *pool, UINT32 allocSize, struct OsMemNodeHead *node, UINT32 nodeSize) |
|
STATIC INLINE VOID | OsMemMergeNodeForReAllocBigger (VOID *pool, UINT32 allocSize, struct OsMemNodeHead *node, UINT32 nodeSize, struct OsMemNodeHead *nextNode) |
|
STATIC INLINE VOID * | OsGetRealPtr (const VOID *pool, VOID *ptr) |
|
STATIC INLINE VOID * | OsMemRealloc (struct OsMemPoolHead *pool, const VOID *ptr, struct OsMemNodeHead *node, UINT32 size, UINT32 intSave) |
|
VOID * | LOS_MemRealloc (VOID *pool, VOID *ptr, UINT32 size) |
| 按size大小重新分配内存块,并将原内存块内容拷贝到新内存块。如果新内存块申请成功,则释放原内存块 更多...
|
|
UINT32 | LOS_MemFreeByTaskID (VOID *pool, UINT32 taskID) |
|
UINT32 | LOS_MemPoolSizeGet (const VOID *pool) |
| 获取指定动态内存池的总大小 更多...
|
|
UINT32 | LOS_MemTotalUsedGet (VOID *pool) |
| 获取指定动态内存池的总使用量大小 更多...
|
|
STATIC INLINE VOID | OsMemMagicCheckPrint (struct OsMemNodeHead **tmpNode) |
|
STATIC UINT32 | OsMemAddrValidCheckPrint (const VOID *pool, struct OsMemFreeNodeHead **tmpNode) |
|
STATIC UINT32 | OsMemIntegrityCheckSub (struct OsMemNodeHead **tmpNode, const VOID *pool, const struct OsMemNodeHead *endNode) |
|
STATIC UINT32 | OsMemFreeListNodeCheck (const struct OsMemPoolHead *pool, const struct OsMemFreeNodeHead *node) |
|
STATIC VOID | OsMemPoolHeadCheck (const struct OsMemPoolHead *pool) |
|
STATIC UINT32 | OsMemIntegrityCheck (const struct OsMemPoolHead *pool, struct OsMemNodeHead **tmpNode, struct OsMemNodeHead **preNode) |
|
STATIC VOID | OsMemNodeInfo (const struct OsMemNodeHead *tmpNode, const struct OsMemNodeHead *preNode) |
|
STATIC VOID | OsMemIntegrityCheckError (struct OsMemPoolHead *pool, const struct OsMemNodeHead *tmpNode, const struct OsMemNodeHead *preNode, UINT32 intSave) |
|
UINT32 | LOS_MemIntegrityCheck (const VOID *pool) |
| 对指定内存池做完整性检查 更多...
|
|
STATIC INLINE VOID | OsMemInfoGet (struct OsMemPoolHead *poolInfo, struct OsMemNodeHead *node, LOS_MEM_POOL_STATUS *poolStatus) |
|
UINT32 | LOS_MemInfoGet (VOID *pool, LOS_MEM_POOL_STATUS *poolStatus) |
| LOS_MemInfoGet
获取指定内存池的内存结构信息,包括空闲内存大小、已使用内存大小、空闲内存块数量、已使用的内存块数量、最大的空闲内存块大小 更多...
|
|
UINT32 | LOS_MemFreeNodeShow (VOID *pool) |
| 打印指定内存池的空闲内存块的大小及数量 更多...
|
|
STATUS_T | OsKHeapInit (size_t size) |
| 内核空间动态内存(堆内存)初始化 , 争取系统动态内存池 更多...
|
|
BOOL | OsMemIsHeapNode (const VOID *ptr) |
|
http://www.gii.upv.es/tlsf/files/ecrts04_tlsf.pdf
https://www.codenong.com/cs106845116/ TLSF算法(一)分配中的位图计算
基本概念
内存管理模块管理系统的内存资源,它是操作系统的核心模块之一,主要包括内存的初始化、分配以及释放。
OpenHarmony LiteOS-A的堆内存管理提供内存初始化、分配、释放等功能。在系统运行过程中,堆内存管理
模块通过对内存的申请/释放来管理用户和OS对内存的使用,使内存的利用率和使用效率达到最优,同时最大限度地解决系统的内存碎片问题。
运行机制
堆内存管理,即在内存资源充足的情况下,根据用户需求,从系统配置的一块比较大的连续内存
(内存池,也是堆内存)中分配任意大小的内存块。当用户不需要该内存块时,又可以释放回系统供下一次使用。
与静态内存相比,动态内存管理的优点是按需分配,缺点是内存池中容易出现碎片。
OpenHarmony LiteOS-A堆内存在TLSF算法的基础上,对区间的划分进行了优化,获得更优的性能,降低了碎片率。
动态内存核心算法框图如下:
根据空闲内存块的大小,使用多个空闲链表来管理。根据内存空闲块大小分为两个部分:[4, 127]和[27, 231],如上图size class所示:
1. 对[4,127]区间的内存进行等分,如上图下半部分所示,分为31个小区间,每个小区间对应内存块大小为4字节的倍数。
每个小区间对应一个空闲内存链表和用于标记对应空闲内存链表是否为空的一个比特位,值为1时,空闲链表非空。
[4,127]区间的31个小区间内存对应31个比特位进行标记链表是否为空。
2. 大于127字节的空闲内存块,按照2的次幂区间大小进行空闲链表管理。总共分为24个小区间,每个小区间又等分为8个二级小区间,
见上图上半部分的Size Class和Size SubClass部分。每个二级小区间对应一个空闲链表和用于标记对应空闲内存链表是否为空的一个比特位。
总共24*8=192个二级小区间,对应192个空闲链表和192个比特位进行标记链表是否为空。
例如,当有40字节的空闲内存需要插入空闲链表时,对应小区间[40,43],第10个空闲链表,位图标记的第10比特位。
把40字节的空闲内存挂载第10个空闲链表上,并判断是否需要更新位图标记。当需要申请40字节的内存时,
根据位图标记获取存在满足申请大小的内存块的空闲链表,从空闲链表上获取空闲内存节点。如果分配的节点大于需要申请的内存大小,
进行分割节点操作,剩余的节点重新挂载到相应的空闲链表上。当有580字节的空闲内存需要插入空闲链表时,对应二级小区间[29,29+2^6],
第31+2*8=47个空闲链表,并使用位图的第47个比特位来标记链表是否为空。把580字节的空闲内存挂载第47个空闲链表上,并判断是否需要更新位图标记。
当需要申请580字节的内存时,根据位图标记获取存在满足申请大小的内存块的空闲链表,从空闲链表上获取空闲内存节点。
如果分配的节点大于需要申请的内存大小,进行分割节点操作,剩余的节点重新挂载到相应的空闲链表上。如果对应的空闲链表为空,
则向更大的内存区间去查询是否有满足条件的空闲链表,实际计算时,会一次性查找到满足申请大小的空闲链表。
内存信息包括内存池大小、内存使用量、剩余内存大小、最大空闲内存、内存水线、内存节点数统计、碎片率等。
内存水线:即内存池的最大使用量,每次申请和释放时,都会更新水线值,实际业务可根据该值,优化内存池大小;
碎片率:衡量内存池的碎片化程度,碎片率高表现为内存池剩余内存很多,但是最大空闲内存块很小,可以用公式(fragment=100-最大空闲内存块大小/剩余内存大小)来度量;
内存管理结构如下图所示:
- 版本
- 作者
- weharmonyos.com | 鸿蒙研究站 | 每天死磕一点点
- 日期
- 2021-11-19
在文件 los_memory.c 中定义.