SylixOS 系统内存管理分为两大类: 内存堆管理和虚拟内存管理. 对用户来说内存堆管理的分配最小单位为 1 个字节, 虚拟内存管理分配最小单位为 1 个页面(通常为 4096 字节)
内核部分
操作系统内建的内存堆管理分为两大类: 核心内存堆和系统内存堆, 这两个内存堆对于操作系统来说都是具有持久性的, 换句话说, 只要内核没有重启, 分配出的内存在整个内核都是唯一的, 并且持久有效的.
-> 核心内存堆主要为操作系统内核对象提供动态内存, 它的访问函数即如下所示:
ker_malloc(), ker_free(), ker_zalloc(), ker_malloc_align(), ker_realloc()
-> 系统内存堆主要为操作系统外围管理程序提供动态内存, 例如: 设备驱动等等, 它的访问函数即如下所示:
sys_malloc(), sys_free(), sys_zalloc(), sys_malloc_align(), sys_realloc()
在 linux 系统中, 驱动程序通常使用 kmalloc(), vmalloc() 来分配内存. 与 linux 类似. SylixOS 驱动程序通常使用"系统内存堆"来分配内存: 他们有以下对应关系: (在 linux/compat.h 中)
#define kmalloc(a, b) sys_malloc(a)
#define vmalloc(a, b) sys_malloc(a)
#define kfree(p) sys_free()
#define vfree(p) sys_free()
特殊情况: 当驱动程序需要分配 DMA 缓冲内存, 则必须使用 vmmDmaAlloc() 系列函数, 这些函数可分配出指定对齐关系的物理页面(非CACHE)供 DMA 使用.
应用程序部分:
-> 操作系统为应用程序留有一组内存堆访问函数(符合 C STDLIB 标准), 它的内存是通过"系统内存堆"来分配的, 它的访问函数即如下所示:
malloc(), free(), zalloc(), memalign(), realloc() ...
当应用程序和内核一起编译为可执行镜像时, 应用程序使用的动态内存就是"系统内存堆"分配的函数, 它的属性与其他通过系统内存堆分配出的内存相同: 内存在整个内核都是唯一的, 并且持久有效的.
当然, SylixOS 操作系统可以通过动态装载的方式运行应用程序, 如果没有特殊的处理, 它所使用的动态内存与上面所说的相同, 都是使用"系统内存堆".
特殊情况: 当应用程序需要的动态内存很大, 或者应用程序有非常难以查找的内存泄漏存在, 则推荐使用 mpdm 补丁来解决此问题. 源代码就是 vpmpdm.c.module
vpmpdm 是 virtual process module private dynamic memory 的缩写, 译为: 虚拟进程私有动态内存.
"私有"一词主要说明此内存区是随模块或应用的加载而产生, 随模块或应用的卸载而消亡.
vpmpdm 内部有一个构造函数, 当模块或应用加载时, 他将通过虚拟内存管理来分配一个虚拟内存空间,(空间的大小将通过环境变量 SO_MEM_PAGES 决定), 然后在此空间上创建一个内存堆.
创建出来的内存堆对整个模块或应用都是透明的, 然后 mpdm 重新定义了 malloc(), free(), zalloc(), memalign(), realloc() … 这些用户内存分配函数,
这时, 如果模块或应用内部有相应的内存分配操作时, 这些操作将会被重定向到这组函数上.
如果模块或应用被卸载, 则 vpmpdm 内部的析构函数将释放整个虚拟内存空间.
如上所说可知, vpmpdm 补丁分配出的内存是不持久的, 当模块卸载时, 他将会被释放.
关于 vpmpdm 的使用方法:
当用户编译单一(无依存关系)的应用程序或模块时, 只要 vpmpdm 源码加入工程, 或者工程链接时连接 vpmpdm 的静态/动态库就可以了. 推荐将 vpmpdm 编译成 libvpmpdm.so 放在 /lib 中,
然后应用程序编译时选择依赖这个库就可以了, 装载器在装载应用程序时会自动装载 vpmpdm 库, gcc 编译器 -lvpmpdm 表示依赖此库.
|