1. 对内存分配子的字段总结:
struct apr_allocator_t {
apr_uint32_t max_index;
apr_uint32_t max_free_index;
apr_uint32_t current_free_index;
#if APR_HAS_THREADS
apr_thread_mutex_t *mutex;
#endif /* APR_HAS_THREADS */
apr_pool_t *owner;
apr_memnode_t *free[MAX_INDEX];
};
首先需要指出,分配子中的free数组中的内存都是可用内存,也就是说还没有被使用。
max_index:free指针数组的下标,它指的是free数组中
已存在的最大内存块链表的索引值。
max_free_index:用于记录内存分配子中最多可用容纳的内存空间大小。
current_free_index:用于记录内存分配子中当前可以继续容纳的内存空间的大小,该字段和max_free_index一起用于控制内存分配子的内存大小。
owner:指示该分配子属于哪个内存池。
free:指向一组链表的头结点,该链表中每个结点指向内存结点组成的链表。
内存分配子的结构图如下:
在Apache源代码中,每个内存结点的字段index的计算方式如下:
index=(size>>BOUNDARY)-1 其中BOUNDARY=12
但是,在计算调整后的max_free_index字段时,并没有减去1,比如在函数apr_allocator_max_free_set中,
max_free_index=APR_ALIGN(size,BOUNDARY_SIZE)>>BOUNDARY_INDEX;
其中BOUNDARY_SIZE=1<<BOUNDARY_INDEX ,即BOUNDARY_SIZE=2^12=4K
因此max_free_index仅仅记录的是内存大小相对于4K的整数值。current_free_index同样如此,这一点可以在内存分配子的结点回收函数allocator_free中可以体现,而max_index是与index对应的,因此也减去过1。见下面加黑和加红部分:
void allocator_free(apr_allocator_t *allocator, apr_memnode_t *node)
{
apr_memnode_t *next, *freelist = NULL;
apr_uint32_t index, max_index;
apr_uint32_t max_free_index, current_free_index;
#if APR_HAS_THREADS
if (allocator->mutex)
apr_thread_mutex_lock(allocator->mutex);
#endif /* APR_HAS_THREADS */
max_index = allocator->max_index;
max_free_index = allocator->max_free_index;
current_free_index = allocator->current_free_index;
/* Walk the list of submitted nodes and free them one by one,
* shoving them in the right 'size' buckets as we go.
*/
do {
next = node->next;
index = node->index;
if (max_free_index != APR_ALLOCATOR_MAX_FREE_UNLIMITED
&&
index + 1 > current_free_