• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Heap Memory Management<a name="EN-US_TOPIC_0000001123795191"></a>
2
3-   [Basic Concepts](#section449414395916)
4-   [Working Principles](#section465085575911)
5-   [Development Guidelines](#section577019272015)
6    -   [When to Use](#section326917198583)
7    -   [Available APIs](#section1032331584)
8    -   [How to Develop](#section07271773592)
9    -   [Development Example](#section84931234145913)
10    -   [Verification](#section165233233917)
11
12
13## Basic Concepts<a name="section449414395916"></a>
14
15Memory management module, one of the core modules of the OS, manages the memory resources of the system. Memory management involves memory initialization, allocation, and release. The heap memory management of the OpenHarmony LiteOS-A provides functions such as memory initialization, allocation, and release. While the OS is running, the heap memory management module manages the memory usage of users and the OS by allocating and releasing memory. This helps achieve the optimal memory usage and usage efficiency and minimize memory fragments.
16
17## Working Principles<a name="section465085575911"></a>
18
19Heap memory management allows memory blocks of any size to be allocated from a large contiguous memory \(memory pool or heap memory\) configured in the system based on user demands when memory resources are sufficient. The memory block can be released for further use when not required. Heap memory management is a type of dynamic memory management. Compared with static memory management, dynamic memory management allows memory allocation on demand but causes fragmentation of memory. The heap memory of the OpenHarmony LiteOS-A has optimized the memory space partitioning based on the Two-Level Segregate Fit \(TLSF\) algorithm to achieve higher performance and minimize fragmentation.  [Figure 1](#fig14558185217397)  shows the core algorithm of the heap memory management.
20
21**Figure  1**  Heap memory core algorithm<a name="fig14558185217397"></a>
22![](figure/heap-memory-core-algorithm.png "heap-memory-core-algorithm")
23
24Multiple free lists are used for management based on the size of the free memory block. The free memory blocks are divided into two parts: \[4, 127\] and \[2<sup>7</sup>, 2<sup>31</sup>\], as indicated by the size class in the above figure.
25
261.  The memory in the range of \[4, 127\] \(lower part in the figure\) is equally divided into 31 parts. The size of the memory block corresponding to each part is a multiple of 4 bytes. Each part corresponds to a free list and a bit that indicates whether the free list is empty. The value  **1**  indicates that the free list is not empty. There are 31 bits corresponding to the 31 memory parts in the range of \[4, 127\].
272.  The memory greater than 127 bytes is managed in power of two increments. The size of each range is \[2^n, 2^\(n+1\) -1\], where n is an integer in \[7, 30\]. This range is divided into 24 parts, each of which is further divided into 8 second-level \(L2\) ranges, as shown in Size Class and Size SubClass in the upper part of the figure. Each L2 range corresponds to a free list and a bit that indicates whether the free list is empty. There are a total of 192 \(24 x 8\) L2 ranges, corresponding to 192 free lists and 192 bits.
28
29For example, insert 40-byte free memory to a free list. The 40-byte free memory corresponds to the 10th free list in the range of \[40, 43\], and the 10th bit indicates the use of the free list. The system inserts the 40-byte free memory to the 10th free list and determines whether to update the bitmap flag. When 40-byte memory is requested, the system obtains the free list corresponding to the memory block of the requested size based on the bitmap flag, and then obtains a free memory node from the free list. If the size of the allocated node is greater than the memory requested, the system splits the node and inserts the remaining node to the free list. If 580-byte free memory needs to be inserted to a free list, the 580-byte free memory corresponds to the 47th \(31 + 2 x 8\) free list in L2 range \[2^9, 2^9+2^6\], and the 47th bit indicates the use of the free list. The system inserts the 580-byte free memory to the 47th free list and determines whether to update the bitmap flag. When 580-byte memory is requested, the system obtains the free list corresponding to the memory block of the requested size based on the bitmap flag, and then obtains a free memory node from the free list. If the size of the allocated node is greater than the memory requested, the system splits the node and inserts the remaining node to the free list. If the corresponding free list is empty, the system checks for a free list meeting the requirements in a larger memory range. In actual application, the system can locate the free list that meets the requirements at a time.
30
31The following figure shows the memory management structure.
32
33**Figure  2**  Dynamic memory management structure<a name="fig5395115964114"></a>
34![](figure/dynamic-memory-management-structure-20.png "dynamic-memory-management-structure-20")
35
36-   Memory pool header
37
38    The memory pool header contains the memory pool information, bitmap flag array, and free list array. The memory pool information includes the start address of the memory pool, total size of the heap memory, and attributes of the memory pool. The bitmap flag array consists of seven 32-bit unsigned integers. Each bit indicates whether the free list is inserted with free memory block nodes. The free list contains information about 223 free memory head nodes. The free memory head node information contains a memory node header and information about the previous and next nodes in the free list.
39
40-   Memory pool nodes
41
42    There are three types of nodes: free node, used node, and end node. Each memory node maintains the size and use flag of the memory node and a pointer to the previous memory node in the memory pool. The free nodes and used nodes have a data area, but the end node has no data area.
43
44
45## Development Guidelines<a name="section577019272015"></a>
46
47### When to Use<a name="section326917198583"></a>
48
49Heap memory management is mainly used to dynamically allocate and manage memory ranges requested by users. Heap memory management is mainly used in scenarios where users need to use memory blocks of different sizes. You can obtain a memory block of a specified size by using a dynamic memory application function of the operating system. Once the memory is used up, the memory release function is used to release the occupied memory so that the memory can be reused.
50
51### Available APIs<a name="section1032331584"></a>
52
53The following table describes APIs available for OpenHarmony LiteOS-A heap memory management. For more details about the APIs, see the API reference.
54
55**Table  1**  Heap memory management APIs
56
57<a name="table1415203765610"></a>
58<table><thead align="left"><tr id="row134151837125611"><th class="cellrowborder" valign="top" width="12.85128512851285%" id="mcps1.2.4.1.1"><p id="p16415637105612"><a name="p16415637105612"></a><a name="p16415637105612"></a>Category</p>
59</th>
60<th class="cellrowborder" valign="top" width="29.8029802980298%" id="mcps1.2.4.1.2"><p id="p11415163718562"><a name="p11415163718562"></a><a name="p11415163718562"></a><strong id="b132706141086"><a name="b132706141086"></a><a name="b132706141086"></a>API</strong></p>
61</th>
62<th class="cellrowborder" valign="top" width="57.34573457345735%" id="mcps1.2.4.1.3"><p id="p1641533755612"><a name="p1641533755612"></a><a name="p1641533755612"></a>Description</p>
63</th>
64</tr>
65</thead>
66<tbody><tr id="row0415737175610"><td class="cellrowborder" rowspan="2" valign="top" width="12.85128512851285%" headers="mcps1.2.4.1.1 "><p id="p6485848217"><a name="p6485848217"></a><a name="p6485848217"></a>Initializing or deleting a memory pool</p>
67</td>
68<td class="cellrowborder" valign="top" width="29.8029802980298%" headers="mcps1.2.4.1.2 "><p id="p1448511481314"><a name="p1448511481314"></a><a name="p1448511481314"></a>LOS_MemInit</p>
69</td>
70<td class="cellrowborder" valign="top" width="57.34573457345735%" headers="mcps1.2.4.1.3 "><p id="p94857483110"><a name="p94857483110"></a><a name="p94857483110"></a>Initializes a dynamic memory pool of the specified size.</p>
71</td>
72</tr>
73<tr id="row1841519376561"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p20485134810119"><a name="p20485134810119"></a><a name="p20485134810119"></a>LOS_MemDeInit</p>
74</td>
75<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p154851348113"><a name="p154851348113"></a><a name="p154851348113"></a>Deletes a memory pool. It is valid only when <strong id="b1987930133815"><a name="b1987930133815"></a><a name="b1987930133815"></a>LOSCFG_MEM_MUL_POOL</strong> is enabled.</p>
76</td>
77</tr>
78<tr id="row1187514443616"><td class="cellrowborder" rowspan="4" valign="top" width="12.85128512851285%" headers="mcps1.2.4.1.1 "><p id="p19661710214"><a name="p19661710214"></a><a name="p19661710214"></a>Allocating or releasing dynamic memory</p>
79</td>
80<td class="cellrowborder" valign="top" width="29.8029802980298%" headers="mcps1.2.4.1.2 "><p id="p66111714213"><a name="p66111714213"></a><a name="p66111714213"></a>LOS_MemAlloc</p>
81</td>
82<td class="cellrowborder" valign="top" width="57.34573457345735%" headers="mcps1.2.4.1.3 "><p id="p4661715214"><a name="p4661715214"></a><a name="p4661715214"></a>Allocates memory of the specified size from the dynamic memory pool.</p>
83</td>
84</tr>
85<tr id="row1745415527441"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p116111718218"><a name="p116111718218"></a><a name="p116111718218"></a>LOS_MemFree</p>
86</td>
87<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p1569175218"><a name="p1569175218"></a><a name="p1569175218"></a>Releases the memory allocated from the specified dynamic memory.</p>
88</td>
89</tr>
90<tr id="row19101718144518"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p161417225"><a name="p161417225"></a><a name="p161417225"></a>LOS_MemRealloc</p>
91</td>
92<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p56181718219"><a name="p56181718219"></a><a name="p56181718219"></a>Re-allocates a memory block of the required size and copies data from the original block to the newly allocated bock. If the new memory block is successfully allocated, the original memory block will be released.</p>
93</td>
94</tr>
95<tr id="row1346314166464"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p10610171528"><a name="p10610171528"></a><a name="p10610171528"></a>LOS_MemAllocAlign</p>
96</td>
97<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p26171714214"><a name="p26171714214"></a><a name="p26171714214"></a>Allocates the memory of the specified size and aligned based on the specified bytes from a dynamic memory pool.</p>
98</td>
99</tr>
100<tr id="row28531740101112"><td class="cellrowborder" rowspan="4" valign="top" width="12.85128512851285%" headers="mcps1.2.4.1.1 "><p id="p39818810129"><a name="p39818810129"></a><a name="p39818810129"></a>Obtaining memory pool information</p>
101</td>
102<td class="cellrowborder" valign="top" width="29.8029802980298%" headers="mcps1.2.4.1.2 "><p id="p16981986123"><a name="p16981986123"></a><a name="p16981986123"></a>LOS_MemPoolSizeGet</p>
103</td>
104<td class="cellrowborder" valign="top" width="57.34573457345735%" headers="mcps1.2.4.1.3 "><p id="p129820881212"><a name="p129820881212"></a><a name="p129820881212"></a>Obtains the total size of the specified dynamic memory pool.</p>
105</td>
106</tr>
107<tr id="row34281341171114"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p0987831214"><a name="p0987831214"></a><a name="p0987831214"></a>LOS_MemTotalUsedGet</p>
108</td>
109<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p1598889124"><a name="p1598889124"></a><a name="p1598889124"></a>Obtains the total memory usage of the specified dynamic memory pool.</p>
110</td>
111</tr>
112<tr id="row112644551119"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p398208201215"><a name="p398208201215"></a><a name="p398208201215"></a>LOS_MemInfoGet</p>
113</td>
114<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p139815820126"><a name="p139815820126"></a><a name="p139815820126"></a>Obtains the memory structure information of the specified memory pool, including the free memory, used memory, number of free memory blocks, number of used memory blocks, and maximum size of the free memory block.</p>
115</td>
116</tr>
117<tr id="row1357684518110"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p3981383125"><a name="p3981383125"></a><a name="p3981383125"></a>LOS_MemPoolList</p>
118</td>
119<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p998148101218"><a name="p998148101218"></a><a name="p998148101218"></a>Prints information about all initialized memory pools in the system, including the start address, size, total free memory, used memory, maximum size of the free memory block, number of free memory blocks, and number of used memory blocks of each memory pool. It is valid only when <strong id="b18583195311398"><a name="b18583195311398"></a><a name="b18583195311398"></a>LOSCFG_MEM_MUL_POOL</strong> is enabled.</p>
120</td>
121</tr>
122<tr id="row14824879135"><td class="cellrowborder" valign="top" width="12.85128512851285%" headers="mcps1.2.4.1.1 "><p id="p1058973361319"><a name="p1058973361319"></a><a name="p1058973361319"></a>Obtaining memory block information</p>
123</td>
124<td class="cellrowborder" valign="top" width="29.8029802980298%" headers="mcps1.2.4.1.2 "><p id="p989115206287"><a name="p989115206287"></a><a name="p989115206287"></a>LOS_MemFreeNodeShow</p>
125</td>
126<td class="cellrowborder" valign="top" width="57.34573457345735%" headers="mcps1.2.4.1.3 "><p id="p437618158141"><a name="p437618158141"></a><a name="p437618158141"></a>Prints the size and number of free memory blocks in the specified memory pool.</p>
127</td>
128</tr>
129<tr id="row0715201211155"><td class="cellrowborder" valign="top" width="12.85128512851285%" headers="mcps1.2.4.1.1 "><p id="p13599202711513"><a name="p13599202711513"></a><a name="p13599202711513"></a>Checking memory pool integrity</p>
130</td>
131<td class="cellrowborder" valign="top" width="29.8029802980298%" headers="mcps1.2.4.1.2 "><p id="p5784183891513"><a name="p5784183891513"></a><a name="p5784183891513"></a>LOS_MemIntegrityCheck</p>
132</td>
133<td class="cellrowborder" valign="top" width="57.34573457345735%" headers="mcps1.2.4.1.3 "><p id="p15644611153"><a name="p15644611153"></a><a name="p15644611153"></a>Checks the integrity of the specified memory pool. It is valid only when <strong id="b1827512584018"><a name="b1827512584018"></a><a name="b1827512584018"></a>LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK</strong> is enabled.</p>
134</td>
135</tr>
136</tbody>
137</table>
138
139>![](../public_sys-resources/icon-note.gif) **NOTE:**
140>-   The dynamic memory module manages memory through control block structures, which consume extra memory. Therefore, the actual memory space available to users is less than the value of  **OS\_SYS\_MEM\_SIZE**.
141>-   The  **LOS\_MemAllocAlign**  and  **LOS\_MemMallocAlign**  APIs consume extra memory for memory alignment, which may cause memory loss. When the memory used for alignment is freed up, the lost memory will be reclaimed.
142
143### How to Develop<a name="section07271773592"></a>
144
145The typical development process of dynamic memory is as follows:
146
1471.  Call the  **LOS\_MemInit**  API to initialize a memory pool.
148
149    After a memory pool is initialized, a memory pool control header and end node will be generated, and the remaining memory is marked as free nodes. The end node is the last node in the memory pool, and its size is  **0**.
150
151
1521.  Call the  **LOS\_MemAlloc**  API to allocate dynamic memory of any size.
153
154    The system checks whether the dynamic memory pool has free memory blocks greater than the requested size. If yes, the system allocates a memory block and returns the pointer to the memory block. If no, the system returns NULL. If the memory block allocated is greater than the requested size, the system splits the memory block and inserts the remaining memory block to the free list.
155
156
1571.  Call the  **LOS\_MemFree**  API to release dynamic memory.
158
159    The released memory block can be reused. When  **LOS\_MemFree**  is called, the memory block will be reclaimed and marked as free nodes. When memory blocks are reclaimed, adjacent free nodes are automatically merged.
160
161
162### Development Example<a name="section84931234145913"></a>
163
164The example below implements the following:
165
1661.  Initialize a dynamic memory pool.
1672.  Allocate a memory block from the dynamic memory pool.
1683.  Store a piece of data in the memory block.
1694.  Print the data in the memory block.
1705.  Release the memory block.
171
172The sample code is as follows:
173
174```
175#include "los_memory.h"
176
177#define TEST_POOL_SIZE (2*1024*1024)
178__attribute__((aligned(4))) UINT8 g_testPool[TEST_POOL_SIZE];
179
180VOID Example_DynMem(VOID)
181{
182    UINT32 *mem = NULL;
183    UINT32 ret;
184
185 /* Initialize the memory pool. */
186    ret = LOS_MemInit(g_testPool, TEST_POOL_SIZE);
187    if (LOS_OK  == ret) {
188        printf("Mem init success!\n");
189    } else {
190        printf("Mem init failed!\n");
191        return;
192    }
193
194    /* Allocate memory.*/
195    mem = (UINT32 *)LOS_MemAlloc(g_testPool, 4);
196    if (NULL == mem) {
197        printf("Mem alloc failed!\n");
198        return;
199    }
200    printf("Mem alloc success!\n");
201
202    /* Assign a value.*/
203    *mem = 828;
204    printf("*mem = %d\n", *mem);
205
206    /* Release memory.*/
207    ret = LOS_MemFree(g_testPool, mem);
208    if (LOS_OK == ret) {
209        printf("Mem free success!\n");
210    } else {
211        printf("Mem free failed!\n");
212    }
213
214    return;
215}
216UINT32 ExampleDynMemEntry(VOID)
217{
218    UINT32 ret;
219    TSK_INIT_PARAM_S initParam = {0};
220    initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_DynMem;
221    initParam.usTaskPrio = 10;
222    initParam.pcName = "Example_DynMem";
223    initParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;
224    initParam.uwResved   = LOS_TASK_STATUS_DETACHED;
225
226    /* Create a task with a higher priority. The task will not be executed immediately after being created, because task scheduling is locked.*/
227    ret = LOS_TaskCreate(&g_taskHiID, &initParam);
228    if (ret != LOS_OK) {
229        LOS_TaskUnlock();
230        PRINTK("Example_DynMem create Failed! ret=%d\n", ret);
231        return LOS_NOK;
232    }
233    PRINTK("Example_DynMem create Success!\n");
234    while(1){};
235    return LOS_OK;
236}
237```
238
239### Verification<a name="section165233233917"></a>
240
241The output is as follows:
242
243```
244Mem init success!
245Mem alloc success!
246*mem = 828
247Mem free success!
248```
249
250