有时候为了确定硬件平台应该采购多大的DDR或者考虑小内存平台是否能跑起sylixos或单纯的就想知道开启了许多应用后的系统当前内存的实际使用量,我们就需要计算sylixos系统当前实际耗费内存大小。
本文以zynq7000为例进行说明。
硬件平台的内存排布
如上图是zynq7000的内存空间排布图,里面有SOC自带的OCM内存区,也有外接的DDR内存区。其中OCM内存一般是给BOOT ROM和FSBL阶段使用,uboot阶段还会使用DDR内存前面一部分,剩下的一般都交给操作系统来使用。
zynq7000的DDR内存区有1GB的空间,前面1MB还和OCM空间重叠,不能被访问。实际系统的中的DDR也不一定是1GB,也可能是128MB/256MB/512MB等。
SylixOS 的内存排布
一个系统可能有多块物理内存,sylixos并不会全部使用,而是只用指定的那部分。sylixos 会把分配给它的物理内存分为4个区来处理,详见《SylixOS内存空间映射关系》。
- TEXT分区用来存放系统的镜像文件xxxx.bin,分区是要比这个文件大的,有时会大很多,多出的这些内存也不会被使用。
- DATA分区除去放置.data段和.bss段外,剩余空间都是作为内核堆来管理的。内核堆是动分配的,可能占用率很低。
- DMA和APP分区都是动态分配的,使用利率可以查到。
- 4个区的大小分配可以从bsp工程的配置文件中找到。
- 运行过程中通过free命令可以查看到一些重要的内存消耗状态。
- kersys就是系统堆,可以查到总大小、当前使用量和最大使用量。
- vmm physical zone列表中有两行,其中第一行就是DMA分区地址、大小和使用量。第二行是APP分区地址、大小和使用量。
- 再往下面看,分别是sylixos管理的总物理内存大小,VMM管理内存总大小(包括DMA和APP分区)和VMM管理内存空闲总大小。
计算方法
sylixos实际消耗的内存分两类,固定消耗类和动态消耗类。
TEXT分区中是固定消耗类,只包括系统镜像大小,一般就是uboot加载的bin文件的大小。但有时加载的是elf文件,则并不是该文件的大小,而是链接后实际占用TEXT分区的大小,这个不太容易计算,可以通过编译工具链将elf文件生成bin文件,bin文件的大小就是系统镜像实际大小。总之TEXT分区内部还是会有一些剩余,即系统镜像大小为image_size,则text_size - image_size就是浪费的空间。
DATA分区中的.data和.bss段是固定消耗类,这由代码中定义的静态变量决定,会一直占用对应地址的空间,这部分记做data_size。.data和.bss段就是程序中的静态变量,这些静态变量是否被使用就和实现代码有关了,很难汇总出个结果,就当都用了吧。DATA分区的剩余部分都作为系统堆,记做heap_size,系统堆的当前使用量是能通过free命令查到的,则heap_size - heap_used_size就是空闲的内存。
DMA和APP分区都是动态消耗类,只能获取某一时刻的使用量,记做dma_size和app_size。这两个分区也可合称为VMM分区,大小和空闲可以直接从free命令获取,记做vmm_size和vmm_free。
这样sylixos的实际总内存消耗就是:
sylixos_ram_size = image_size + data_size + heap_used_size + vmm_size - vmm_free。
计算举例
以前面收集的zynq7000信息为例,计算实际内存消耗。
- 系统镜像大小为3,334,228B,即image_size = 3.3MB。而TEXT分区实际给了6MB空间,浪费了2.7MB。
- DATA分区大小为128MB,内核堆大小为119.6MB,用了19%。即data_size = 128 - 119.6 = 8.4MB,heap_used_size = 119.6 * 0.19 = 22.7MB。
- VMM分区直接从free命令获取,vmm_size = 894MB,vmm_free = 891MB
sylixos_ram_size
= image_size + data_size + heap_used_size + vmm_size - vmm_free
= 3.3 + 8.4 + 22.7 + 894 - 891
= 37.4MB
即该系统中,实际有DDR内存1024MB,SylixOS管理了1022MB,当前实际占用了37.4MB。