简介:
malloc申请的内存是哪里来的呢?
很多人都说是从堆上来的。回答没错,可堆又是从哪里来的呢?本文结合freeRTOS嵌入式系统简单的介绍一下malloc内存的来历。
内容:
一句话先概括一下堆是从哪里来的,两种方式:
1:堆是编译器静态编译的确定的。
如果你定义了一个全局的数组,那么编译器编译是否要为这个数组分配空间呢?答案是肯定的。
如果有个嵌入式系统硬件上可用RAM只有175KB,编译freeRTOS,添加相关应用,生成了程序(即txt段,bss段,data段组合)。
假如查看map文件发现,.txt段,.bss段,.data段占用75k,还有100KB。这100KB干嘛用呢,一般剩余的内从作为系统的堆栈用。
如何才能作为系统的堆栈用呢?让操作系统来进行管理。
对于freeRTOS系统很简单,就是定义一个可配置的数组,让编译器为其分配内存。如下
/* Allocate the memory for the heap. */
static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
把其作为系统的heap,进行初始化。其他所有内存都从这里获取。
于是有了malloc等相关的内存管理函数。系统中需要动态内存的都通过OS的内存管理
接口分配内存。甚至包含任务创建所需要的内存,如TCB,任务所需要的栈等。
2:堆是动态确定的。
编译器算出heap的起点。
pHeap=编译地址空间基地址(可以作为参数传递给编译器)+ (.txt段,.bss段,.data段等总和)。
然后系统使用这个指针不停的加。可参照brk的实现。
最后随便说点:
mmu的出现,可以说改变了编译器,编译器再也不用关心物理地址。将编译地址空间变为0g-4g(或者说无限大)。
对于linux一个进程,其首先载入elf文件,然后初始化task,堆栈指针初始化为
pStack=4g -(elf .txt段,.bss段,.data段等总和)。向上生长。
pHeap=4g 向下生长。
此时堆的本质已经变成了动态申请的虚存空间。