计算CellBlock的大小

来源:互联网 发布:手机解压软件中文版 编辑:程序博客网 时间:2024/06/06 00:08

转载,请注明出处!

在Collector.h文件中有如下一行代码:

const size_t CELLS_PER_BLOCK = (BLOCK_SIZE - sizeof(Heap*)) * 8 * CELL_SIZE / (8 * CELL_SIZE + 1) / CELL_SIZE; // one bitmap byte can represent 8 cells.
我一直不明白这行计算式的原理何在?仔细阅读了相关类之后,心中有所悟。首先阅读Heap::cellBlock函数的实现。如下,
inline CollectorBlock* Heap::cellBlock(const JSCell* cell){    return reinterpret_cast<CollectorBlock*>(reinterpret_cast<uintptr_t>(cell)&BLOCK_MASK);}
根据这个函数可以得出一个结论,CollectorBlock对象的地址一定是按照BLOCK_SIZE对齐的。CollectorBlock的定义如下,
class CollectorBlock {public:    CollectorCell cells[CELLS_PER_BLOCK];    CollectorBitmap marked;    Heap* heap;};

CollectorBlock对象占用的内存大小为:CELL_SIZE * CELLS_PER_BLOCK + CELLS_PER_BLOCK/8 + sizeof(Heap*),这个大小是以字节为单位的。很明显这个大小应该小于BLOCK_SIZE,即CELL_SIZE * CELLS_PER_BLOCK + CELLS_PER_BLOCK/8 + sizeof(Heap*) <= BLOCK_SIZE。如果将这个不等式看做等式,那么可以经过几步转化则可以得到文件中的计算式。转化步骤如下,

(8 * CELL_SIZE * CELLS_PER_BLOCK + CELLS_PER_BLOCK) / 8 = (BLOCK_SIZE - sizeof(Heap*))

(8 * CELL_SIZE + 1) * CELLS_PER_BLOCK = (BLOCK_SIZE - sizeof(Heap*)) * 8

CELLS_PER_BLOCK = (BLOCK_SIZE - sizeof(Heap*)) * 8 / (8 * CELL_SIZE + 1)

CELLS_PER_BLOCK = (BLOCK_SIZE - sizeof(Heap*)) * 8 * CELL_SIZE / (8 * CELL_SIZE + 1) * CELL_SIZE

CELLS_PER_BLOCK = (BLOCK_SIZE - sizeof(Heap*)) * 8 * CELL_SIZE / (8 * CELL_SIZE + 1) / CELL_SIZE

计算机上除法运算时下取整的。例如:3 / 2 = 1, 100 / 40 = 2等。因此,根据运算式获得的结果不会将BLOCK_SIZE个字节完全占有使用,会遗留一些paddings字节。