[APR源码解析]内存分配current_free_index与max_free_index的作用
current_free_index与max_free_index的作用:
我在看源码时,一直不明白current_free_index与max_free_index的作用,看了很多网上是解释,然后看了无数遍的源码,慢慢知道原来如此。
apr_allocator_max_free_set,这个函数用来设置max_free_index的,其实关键一开始不明白的是不知道max_free_index其实就是一个分配子(allocator)允许容纳内存空间的总大小,主要是因为“_index”这个后缀,apr表示内存的大小不是用size,而是用index,size和index的转换是max_free_index = APR_ALIGN(size, BOUNDARY_SIZE) >> BOUNDARY_INDEX; 所以后面会一直出现allocator->current_free_index += node->index + 1;其实就是增加相应内存块大小(原先还一直认为,为什么一直要加上数组下标)。
所以现在就好理解了:
max_free_index表示allocator最多能容纳内存空间的大小,只不过用index表示而已。
current_free_index表示allocator还能容纳内存空间的大小(或表示剩余空间的大小),也是用index表示。值越大剩余空间就越大。所以在释放allocator_free时,会拿当前要释放的内存的节点的内存大小(用index表示)和剩余空间的大小比较,如果超过了,就将此node(或node链表,程序会一直判断,直达找到该释放的node)的内存释放到系统中。
if (max_free_index != APR_ALLOCATOR_MAX_FREE_UNLIMITED
&& index + 1 > current_free_index) {
node->next = freelist;
freelist = node;
}
这个是用来处理(或node链表,程序会一直判断,直达找到该释放的node)
do {
} while ((node = next) != NULL);
else if (index < MAX_INDEX) { /* Add the node to the appropiate 'size' bucket. Adjust * the max_index when appropiate. */ if ((node->next = allocator->free[index]) == NULL && index > max_index) { max_index = index; } allocator->free[index] = node; if (current_free_index >= index + 1) current_free_index -= index + 1; else current_free_index = 0; }
这个代码是将node放入allocator的“规则块”中。放入时,永远是放在每个node链表的第一个节点中(而不是链表的尾部)allocator->free[index] = node;为链表的第一个节点,以前那个节点被放在node->next上(node->next = allocator->free[index])。如果index对应的free中一开始就没有节点,此index大小大于原来的max_index,就将max_index设置为index。最后将剩余空间大小减去放入的节点的大小。
还有从allocator拿内存时,并不是很死板的去取符合大小的节点。而是取适合大小的节点(就是取和它相同大小或比它大的内存节点,当然此时有可能会浪费内存),这样做的目的是因为取有的总比重新分配的要好的。要知道allocator中有的的内存不用其实比浪费更加浪费,毕竟系统内存是很宝贵的