Chinaunix首页 | 论坛 | 博客
  • 博客访问: 68154
  • 博文数量: 19
  • 博客积分: 425
  • 博客等级: 下士
  • 技术积分: 239
  • 用 户 组: 普通用户
  • 注册时间: 2011-10-08 15:35
文章分类

全部博文(19)

文章存档

2012年(2)

2011年(17)

我的朋友

分类: LINUX

2011-10-08 15:43:09

initStaticVars()里面首先会调用SizeMap.initSizeMap是一个非常关键的数据结构,下面我们对他先进行分析。

关于SizeMap结构(common.cccommon.h

SizeMap里面涉及到几个关键的数据结构class_array_class_to_size_class_to_pages_num_objects_to_move_。其中class_array将一个size映射成为一个class num(总共61num),根据这个num可以从class_to_size_class_to_pages_拿出这个class可分配obj的最大size,以及一次从系统中alloc出多少个页面。地址映射到class_arrayindex方法按照下图所示:

// Sizes <= 1024 have an alignment >= 8.  So for such sizes we have an

  // array indexed by ceil(size/8).  Sizes > 1024 have an alignment >= 128.

  // So for these larger sizes we have an array indexed by ceil(size/128).

  //

  // We flatten both logical arrays into one physical array and use

  // arithmetic to compute an appropriate index.  The constants used by

  // ClassIndex() were selected to make the flattening work.

  //

  // Examples:

  //   Size       Expression                      Index

  //   -------------------------------------------------------

  //   0          (0 + 7) / 8                     0

  //   1          (1 + 7) / 8                     1

  //   ...

  //   1024       (1024 + 7) / 8                  128

  //   1025       (1025 + 127 + (120<<7)) / 128   129

  //   ...

  //   32768      (32768 + 127 + (120<<7)) / 128  376

num_objects_to_move_保存了每次在主heap区和per-thread heap区之间移动相应kClassNum指定obj的数量。这样是为了平衡移动obj数量的开销,次数和内存浪费数量之间的平衡。以下函数就是主要做上面四个数据结构的初始化工作。

void SizeMap::Init() {

  // Do some sanity checking on add_amount[]/shift_amount[]/class_array[]

  if (ClassIndex(0) < 0) {

    CRASH("Invalid class index %d for size 0\n", ClassIndex(0));

  }

  if (ClassIndex(kMaxSize) >= sizeof(class_array_)) {

    CRASH("Invalid class index %d for kMaxSize\n", ClassIndex(kMaxSize));

  }

 

  // Compute the size classes we want to use

  int sc = 1;   // Next size class to assign

  int alignment = kAlignment;

  CHECK_CONDITION(kAlignment <= 16);

  int last_lg = -1;

  for (size_t size = kAlignment; size <= kMaxSize; size += alignment) {

    int lg = LgFloor(size);//LgFloor根据提供的size算出需要几bits来对齐

    if (lg > last_lg) {

      // Increase alignment every so often to reduce number of size classes.

               alignment = AlignmentForSize(size);

// separated by 8 bytes(小于16bytes, larger sizes by 16 bytes16128, even larger sizes by 32 bytes1282K(1 << LgFloor(size)) / 8, and so forth. The maximal spacing (for sizes >= ~2K) is 256 bytes.

      last_lg = lg;

    }

    CHECK_CONDITION((size % alignment) == 0);

 

    // Allocate enough pages so leftover is less than 1/8 of total.

    // This bounds wasted space to at most 12.5%.

    size_t psize = kPageSize;

    while ((psize % size) > (psize >> 3)) {

      psize += kPageSize;

    }//此处保证allocpage数组成的空间在被划分为sizeobj的同时确保遗留小于1/8的空余空间

    const size_t my_pages = psize >> kPageShift;

 

    if (sc > 1 && my_pages == class_to_pages_[sc-1]) {

      // See if we can merge this into the previous class without

      // increasing the fragmentation of the previous class.

      const size_t my_objects = (my_pages << kPageShift) / size;

      const size_t prev_objects = (class_to_pages_[sc-1] << kPageShift)

                                  / class_to_size_[sc-1];

      if (my_objects == prev_objects) {

        // Adjust last class to include this size

        class_to_size_[sc-1] = size;

        continue;

/*这部分比较难理解,举例说明,假设my_pages 1size现在为1024,那么my_objects =4,而前面已经建立的class_to_size_=1023,那么prev_objects 也为4那么就用现在的size替换原来的size,这部分的意思就是在同样的page数量和obj数量的情况下得找到每个obj的最大值*/

      }

    }

 

    // Add new class

    class_to_pages_[sc] = my_pages;//初始化class_to_pages_class_to_size_两个数组

    class_to_size_[sc] = size;

    sc++;

  }

  if (sc != kNumClasses) {

    CRASH("wrong number of size classes: found %d instead of %d\n",

          sc, int(kNumClasses));

  }

 

  // Initialize the mapping arrays

  int next_size = 0;

  for (int c = 1; c < kNumClasses; c++) {

    const int max_size_in_class = class_to_size_[c];

    for (int s = next_size; s <= max_size_in_class; s += kAlignment) {

      class_array_[ClassIndex(s)] = c;//初始化class_array,具体可以查看ClassIndex函数

    }

    next_size = max_size_in_class + kAlignment;

  }

 

  // Double-check sizes just to be safe

  for (size_t size = 0; size <= kMaxSize; size++) {

    const int sc = SizeClass(size);

    if (sc <= 0 || sc >= kNumClasses) {

      CRASH("Bad size class %d for %" PRIuS "\n", sc, size);

    }

    if (sc > 1 && size <= class_to_size_[sc-1]) {

      CRASH("Allocating unnecessarily large class %d for %" PRIuS

            "\n", sc, size);

    }

    const size_t s = class_to_size_[sc];

    if (size > s) {

      CRASH("Bad size %" PRIuS " for %" PRIuS " (sc = %d)\n", s, size, sc);

    }

    if (s == 0) {

      CRASH("Bad size %" PRIuS " for %" PRIuS " (sc = %d)\n", s, size, sc);

    }

  }

 

  // Initialize the num_objects_to_move array.

  for (size_t cl = 1; cl  < kNumClasses; ++cl) {

    num_objects_to_move_[cl] = NumMoveSize(ByteSizeForClass(cl));

  }

}

 

阅读(841) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~