欢迎关注VxWorks567 如转发 请标明出处!
从系统内存池(也就是堆)里分配内存,主要用的是ANSI定义的这几个函数
typedef unsigned int size_t;
void *malloc(size_t nBytes);
void *calloc(size_t elemNum, size_t elemSize);
void *realloc(void *pBlock, size_t newSize);
void free(void *ptr);
VxWorks还实现了一个专门与calloc()配合的cfree()
typedef int _Vx_STATUS;
typedef _Vx_STATUS STATUS;
STATUS cfree(char *pBlock);
而存放在堆里的那些内存块具体是如何管理的呢?
Vx5用的策略是First Fit,可以翻译为最先分配算法。在这种策略下,所有的空闲内存块按照地址从低到高排列。当需要申请内存时,从低地址开始查找,第一块满足需求的内存块被分配。所以当系统申请内存的次数比较多了之后,低地址就会留下大量小块内存,导致后期的查找时间略长。大致代码如下
void *memXxxAlloc
(
PART_ID partId, /* memory partition to allocate from */
unsigned nBytes, /* number of bytes to allocate */
unsigned alignment/* boundary to align to */
)
{
...
DL_NODE *pNode = DLL_FIRST(&partId->freeList);
...
while(pNode != NULL)
{
/* fits if:
* - blocksize > requested size + extra room for alignment or,
* - block is already aligned and exactly the right size
*/
if ((NODE_TO_HDR (pNode)->nWords > nWordsExtra) ||
((NODE_TO_HDR (pNode)->nWords == nWords) &&
(ALIGNED (HDR_TO_BLOCK(NODE_TO_HDR(pNode)), alignment))))
break;
pNode = DLL_NEXT (pNode);
}
...
}
而到了Vx6&7,用的策略是Best Fit,可以翻译为最优分配算法。在这种策略下,所有的空闲内存块按照尺寸从小到大排列,并使用AVL(平衡二叉树)维护。当需要申请内存时,从Root节点开始查找,满足需求且尺寸最小的内存块被分配。这种算法会保留大的内存块,提高了整体的分配成功几率,但会多出一些非常小的碎片,不过时间复杂度只有o(ln(N))。大致代码如下
AVLU_NODE *avlXxxGet
(
AVLU_TREE root, /* root node pointer */
UINT key /* search key */
)
{
AVLU_NODE *pNode;
AVLU_NODE *pSuccessor;
pNode = root;
pSuccessor = NULL;
while (pNode != NULL)
{
if (key >= pNode->key)
{
pNode = pNode->right;
}
else
{
pSuccessor = pNode;
pNode = pNode->left;
}
}
return (pSuccessor);
}
当然了,不管哪种策略,在释放内存时,都会自动与前后的空闲块(如果有的话)合并。否则,系统运行一会就都是碎片了。
计算机专业的童鞋应该知道还有一种策略叫Worst Fit,可以翻译为最差分配算法。在这种策略下,所有的空闲内存块按照尺寸从大到小排列。当需要申请内存时,要么分配第一块,要是失败。所以这种算法的分配速度最快,而且很少有小碎片,但是容易造成大块内存申请失败,所以适合待分配内存块比较统一的情况。
你还知道哪些策略?
我是泰山 专注VX好多年! 一起学习 共同进步!