网站首页 Cn029.Com - 西安网吧在线℡

Cn029.Com - 西安网吧在线℡ 西北地区网吧行业门户站点www.cn029.com,本站为您提供网吧维护,每日更新最新网吧技术,政策法规.为您提供各类网管软件,网吧软件,游戏更新软件,承接西部地区网吧维护,希望与您共同讨论网吧经营管理的经验!

投递文章  投稿指南 RSS订阅 西安网吧在线通告:
搜索: 您的位置西安网吧在线Linux-UxLinux精华 → 文章内容

Uclibc中的malloc机制分析(二)

  作者:网络收集   来源:chinaunix.net   更新时间:2008-4-27 5:04:32   【 】  评论:0

三:堆空间的初始化:
     全局变量__malloc_heap表示了整个堆栈空间。它的初始化过程如下示:
struct heap __malloc_heap = HEAP_INIT_WITH_FA (initial_fa);
HEAP_INIT_WITH_FA的定义如下:
#ifdef HEAP_USE_LOCKING
# define HEAP_INIT          { 0, PTHREAD_MUTEX_INITIALIZER }
# define HEAP_INIT_WITH_FA(fa)   { &fa._fa, PTHREAD_MUTEX_INITIALIZER }
#else
# define HEAP_INIT          { 0 }
# define HEAP_INIT_WITH_FA(fa)   { &fa._fa }
#endif
变量initial_fa初始化如下:
HEAP_DECLARE_STATIC_FREE_AREA (initial_fa, 256);
#define HEAP_DECLARE_STATIC_FREE_AREA(name, size)            \

static struct                                     \
  {                                       \
    char space[(size) - sizeof (struct heap_free_area)];         \
    struct heap_free_area _fa;                          \
  } name = { "", { (size), 0, 0 } }

如此可以看出初始化的堆空间为256个字节。从上面的初始化也可以看到,在FA结构的前面静态定义了一个数组空间。这也印证了上面说的“FA结构正好放在空闲区的后面”

四:FA结构的操作:
1:#define HEAP_FREE_AREA_SIZE(fa) ((fa)->size)
FA所代表的空闲区大小,此大小已经包含FA本身占的空间
2: #define HEAP_FREE_AREA_START(fa) ((void *)((char *)(fa + 1) - (fa)->size))
FA所代表空闲区的起始位置。fa+1到达空闲区末端。指针再下移大小个单位,即为空闲区的起始位置
3:#define HEAP_FREE_AREA_END(fa) ((void *)(fa + 1))
返回FA所表示空闲区的末尾。从FA所表示的结构可看出。从FA的地址上移一个FA的大小,刚好到达空闲的末尾
4:#define HEAP_MIN_FREE_AREA_SIZE  \
  HEAP_ADJUST_SIZE (sizeof (struct heap_free_area) + 32)
最少的空闲区大小。空闲区最少要能存上一个heap_free_area大小,此外还要有32字节的空闲,这是从效率来考虑的。Malloc分配内存的时候,有时候它会把一个FA分为两段。如果剩余的内存少于HEAP_MIN_FREE_AREA_SIZE.还不如全部都将内存分配出去。因为维护空闲内存需要影响效率。这从我们后面的malloc 与 free分析中可以看到
5: __heap_delete (struct heap *heap, struct heap_free_area *fa)
该函数是将fa从heap中删除,它的实现如下:
extern inline void
__heap_delete (struct heap *heap, struct heap_free_area *fa)
{
  if (fa->next)
    fa->next->prev = fa->prev;
  if (fa->prev)
    fa->prev->next = fa->next;
  else
    heap->free_areas = fa->next;  //如果删除的是它的首节点
}
     只是一个简单的链表操作,将fa从循环链表中脱节。
6: __heap_link_free_area (struct heap *heap, struct heap_free_area *fa,
                struct heap_free_area *prev,
                struct heap_free_area *next)
从代码注释上看该函数是指prev 与 next 之间的Fa合并到一起。实际上它只是在prev 与next之间插入了一项而已。
实现如下:
extern inline void
__heap_link_free_area (struct heap *heap, struct heap_free_area *fa,
                struct heap_free_area *prev,
                struct heap_free_area *next)
{
  fa->next = next;
  fa->prev = prev;

  if (prev)
    prev->next = fa;
  else
    heap->free_areas = fa;  //插入节点为首节点的情况
  if (next)
    next->prev = fa;
}
7:__heap_link_free_area_after (struct heap *heap,
                   struct heap_free_area *fa,
                   struct heap_free_area *prev)
该函数实际上只是fa链接至prev后。等调用的时候再分析它。
__heap_link_free_area_after (struct heap *heap,
                   struct heap_free_area *fa,
                   struct heap_free_area *prev)
{
  if (prev)
    prev->next = fa;
  else
    heap->free_areas = fa;
  fa->prev = prev;
}
8:__heap_add_free_area (struct heap *heap, void *mem, size_t size,
               struct heap_free_area *prev,
               struct heap_free_area *next)
该函数将从mem地址开始的size大小的内存所代码的FA结构,插入prev和next之间。它的实现如下:
extern inline struct heap_free_area *
__heap_add_free_area (struct heap *heap, void *mem, size_t size,
               struct heap_free_area *prev,
               struct heap_free_area *next)
{
     //先取得内存段所在的FA结构,再将FA结构插入到prev与next之间
  struct heap_free_area *fa = (struct heap_free_area *)
    ((char *)mem + size - sizeof (struct heap_free_area));

  fa->size = size;

//将fa插入prev.next之间
  __heap_link_free_area (heap, fa, prev, next);

  return fa;
}
这函数的实现很有意思。它先取内存段的末地址,然后再返回heap_free_area个单位,存上一个FA结构。这里也印证了,FA结构刚好放在了空闲区的末尾


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u1/51562/showart_459144.html

Tags: 网吧 硬件 价格 最新  
责任编辑:Cn029.Com
  • 请文明参与讨论,禁止漫骂攻击。 用户名:新注册) 验证码: 验证码,看不清楚?请点击刷新验证码

    分 值:100分 85分 70分 55分 40分 25分 10分 0分

    评论总数:0条,平均得分:0[ 查看全部 ] 网友评论
    关于我们 - 联系我们 - 广告服务 - 法律声明 - RSS订阅 - 网站地图 - 返回顶部