apache内存管理
apache内存管理使用了内存池,arp_poo_t结构,使用内存池是必须的。在apache的内存池技术中使用了几个数据结构,apr_memnode_t,apr_allocator_t,就是apache内存节点,apache内存分配器。
其实开始可以猜测一下apache内存池的结构,肯定有list结构,存放实际内存。为什么不用avl树而是用list呢?因为涉及内存管理的操作就是 申请释放,对应list结构就是插入删除节点,那avl树也可以呀!但是avl树结构复杂,操作复杂,占用内存过多。
下面讲解几个内存操作结构:
struct apr_allocator_t {
/** largest used index into free[], always < MAX_INDEX */
/*
free[index]
example:
|——| |——| |——| |_| |_| |_| |_| |
===>| |===> |——|===>|——|===>|_|==>| |==>| |==>| |==>|
|——| |——| |——| |_| |_| |_| |_|
\-----------------used-size-----\-------unused----\
*/
/*
max_free_index就是内存的总大小
*/
apr_size_t max_index;
/** Total size (in BOUNDARY_SIZE multiples) of unused memory before
* blocks are given back. @see apr_allocator_max_free_set().
* @note Initialized to APR_ALLOCATOR_MAX_FREE_UNLIMITED,
* which means to never give back blocks.
*/
apr_size_t max_free_index;
/**
* Memory size (in BOUNDARY_SIZE multiples) that currently must be freed
* before blocks are given back. Range: 0..max_free_index
*/
/*
current_free_index就是现在剩余内存大小,注意index都是下标同时也是大小的意思
*/
apr_size_t current_free_index;
/*
多线程环境下的内存池释放
*/
#if APR_HAS_THREADS
apr_thread_mutex_t *mutex;
#endif /* APR_HAS_THREADS */
/*
当前的poot属于哪一个内存池结构
*/
apr_pool_t *owner;
/**
* Lists of free nodes. Slot 0 is used for oversized nodes,
* and the slots 1..MAX_INDEX-1 contain nodes of sizes
* (i+1) * BOUNDARY_SIZE. Example for BOUNDARY_INDEX == 12:
* slot 0: nodes larger than 81920
* slot 1: size 8192
* slot 2: size 12288
* ...
* slot 19: size 81920
*/
// 核心内存处理结构
// apr_memnode_t {
// struct apr_memnode_t {
// /**/
// apr_memnode_t *next; /**< next memnode */
// /*指向自己的引用*/
// apr_memnode_t **ref; /**< reference to self */
// /*内存池的尺寸*/
// apr_uint32_t index; /**< size */
// /*有多少内存是已经释放的*/
// apr_uint32_t free_index; /**< how much free */
// /*
// 指向第一个已经释放的内存节点位置
// */
// char *first_avail; /**< pointer to first free memory */
// /*
// 指向内存池释放节点指针最后的位置
// */
// char *endp; /**< pointer to end of free memory */
// };
// }
/*free[]memnode节点*/
apr_memnode_t *free[MAX_INDEX];
};
note:上面已经注释了memnode节点,这是实际存内存的结构
下面就是内存池:
struct apr_pool_t {
apr_pool_t *parent;
apr_pool_t *child;
apr_pool_t *sibling;
apr_pool_t **ref;
cleanup_t *cleanups;
cleanup_t *free_cleanups;
/*
分配子
*/
apr_allocator_t *allocator;
struct process_chain *subprocesses;
apr_abortfunc_t abort_fn;
apr_hash_t *user_data;
const char *tag;
#if !APR_POOL_DEBUG
/*
active指向memnode节点
*/
apr_memnode_t *active;
/*
self指向节点自己
*/
apr_memnode_t *self; /* The node containing the pool itself */
char *self_first_avail;
#else /* APR_POOL_DEBUG */
apr_pool_t *joined; /* the caller has guaranteed that this pool
* will survive as long as ->joined */
debug_node_t *nodes;
const char *file_line;
apr_uint32_t creation_flags;
unsigned int stat_alloc;
unsigned int stat_total_alloc;
unsigned int stat_clear;
#if APR_HAS_THREADS
apr_os_thread_t owner;
apr_thread_mutex_t *mutex;
#endif /* APR_HAS_THREADS */
#endif /* APR_POOL_DEBUG */
#ifdef NETWARE
apr_os_proc_t owner_proc;
#endif /* defined(NETWARE) */
cleanup_t *pre_cleanups;
#if APR_POOL_CONCURRENCY_CHECK
#define IDLE 0
#define IN_USE 1
#define DESTROYED 2
volatile apr_uint32_t in_use;
apr_os_thread_t in_use_by;
#endif /* APR_POOL_CONCURRENCY_CHECK */
};
apr_pool_t的结构就是一个树结构,在创建内存池时可以插入不同的内存池对象。
其他结构成员没有注释,但是不影响内存池结构的完整性接下来几天我会注释内存池的申请和释放过程