武汉网站制作哪家强友情链接的概念
SemiSpace的管理新生代内存的类,即我们常听到的from区和to区。from区和to区都由一个SemiSpace对象管理。SemiSpace只管理地址,不负责分配和释放管理的内存。下面是Semispace类的定义。
class SemiSpace BASE_EMBEDDED {public:SemiSpace(int initial_capacity, int maximum_capacity);bool Setup(Address start, int size);void TearDown();bool HasBeenSetup() { return start_ != NULL; }bool Double();Address low() { return start_; }Address high() { return low() + capacity_; }Address age_mark() { return age_mark_; }void set_age_mark(Address mark) { age_mark_ = mark; }// 判断地址a是否在该对象管理的内存中,&address_mask即让a减去size-1的大小。如果等于start说明在管理范围内bool Contains(Address a) {return (reinterpret_cast<uint32_t>(a) & address_mask_) == reinterpret_cast<uint32_t>(start_);}// 类似上面的逻辑,但是堆对象低位是标记,判断时候需要处理一下,加SetUpbool Contains(Object* o) {return (reinterpret_cast<uint32_t>(o) & object_mask_) == object_expected_;}// 距离开始地址的pint SpaceOffsetForAddress(Address addr) { return addr - low(); }private:int capacity_;int maximum_capacity_;Address start_;Address age_mark_;// 见SetUp函数uint32_t address_mask_;uint32_t object_mask_;uint32_t object_expected_;public:TRACK_MEMORY("SemiSpace")
};
下面是SemiSpace类的实现。
SemiSpace
新建一个SemiSpace对象的时候默认初始化某些字段。这些字段的真正设置在SetUp函数。
SemiSpace::SemiSpace(int initial_capacity, int maximum_capacity): capacity_(initial_capacity), maximum_capacity_(maximum_capacity),start_(NULL), age_mark_(NULL) {
}
Setup
Setup函数是初始化SemiSpace对象属性的函数
// 设置管理的地址范围
bool SemiSpace::Setup(Address start, int size) {ASSERT(size == maximum_capacity_);// 判断地址的有效性if (!MemoryAllocator::CommitBlock(start, capacity_)) return false;// 管理地址空间的首地址start_ = start;// 低于有效范围的掩码,即保证相与后的值小于等于管理的地址范围address_mask_ = ~(size - 1);// 计算堆对象地址掩码,低位是标记位,判断的时候需要保留,kHeapObjectTag是堆对象的标记object_mask_ = address_mask_ | kHeapObjectTag;// 见contains函数,对象地址里低位是标记位,判断的时候需要带上object_expected_ = reinterpret_cast<uint32_t>(start) | kHeapObjectTag;// gc相关age_mark_ = start_;return true;
}
TearDown
重置SemiSpace管理的地址,但不负责释放内存。
void SemiSpace::TearDown() {start_ = NULL;capacity_ = 0;
}
Double
“扩容”函数,只不负责内存的分配,只对管理的大小进行扩容。
bool SemiSpace::Double() {// 内存在其他地方分配了,这里校验地址是否合法,即是否分配了if (!MemoryAllocator::CommitBlock(high(), capacity_)) return false;capacity_ *= 2;return true;
}
SemiSpace的功能比较简单,有些属性的使用后续用到的时候再分析。