最近 MaxMemFree をいじっているのですが、この値の効果を調べている時に気なるページを見つけました。
2011年の投稿なので少々古いですが、その中で
I repeated the test and did not see desired effect advertised by the documentation. Then I read in the forums the units may be Mb instead of KB as documented. VMAdmin: Apache MaxMemFree For Lean Memory Control
え、KiBじゃなくてMiBなの?と疑問に思って軽くソースコードを追ってみました。
結論から言うと KiB っぽいです。
server/core.c
AP_INIT_TAKE1("MaxMemFree", ap_mpm_set_max_mem_free, NULL, RSRC_CONF, "Maximum number of 1k blocks a particular childs allocator may hold."),
で、confファイルから値を読み取っています。
server/mpm_common.c
apr_uint32_t ap_max_mem_free = APR_ALLOCATOR_MAX_FREE_UNLIMITED; const char *ap_mpm_set_max_mem_free(cmd_parms *cmd, void *dummy, const char *arg) { long value; const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); if (err != NULL) { return err; } value = strtol(arg, NULL, 0); if (value < 0 || errno == ERANGE) return apr_pstrcat(cmd->pool, "Invalid MaxMemFree value: ", arg, NULL); ap_max_mem_free = (apr_uint32_t)value * 1024; return NULL; }
実際に値をセットする際に読み取り値を1024倍してます。1124行目でデフォルト値の0を設定してます。
srclib/apr/memory/unix/apr_pools.c
APR_DECLARE(void) apr_allocator_max_free_set(apr_allocator_t *allocator, apr_size_t in_size) { apr_uint32_t max_free_index; apr_uint32_t size = (APR_UINT32_TRUNC_CAST)in_size; #if APR_HAS_THREADS apr_thread_mutex_t *mutex; mutex = apr_allocator_mutex_get(allocator); if (mutex != NULL) apr_thread_mutex_lock(mutex); #endif /* APR_HAS_THREADS */ max_free_index = APR_ALIGN(size, BOUNDARY_SIZE) >> BOUNDARY_INDEX; allocator->current_free_index += max_free_index; allocator->current_free_index -= allocator->max_free_index; allocator->max_free_index = max_free_index; if (allocator->current_free_index > max_free_index) allocator->current_free_index = max_free_index; #if APR_HAS_THREADS if (mutex != NULL) apr_thread_mutex_unlock(mutex); #endif }
BOUNDARY_SIZE の倍数に切り上げて max_free_index とやらを設定しているようですが、
まだ、読み切れてないです……
あとは諸々の宣言部
srclib/apr/memory/unix/apr_pools.c
#define BOUNDARY_INDEX 12 #define BOUNDARY_SIZE (1 << BOUNDARY_INDEX)
srclib/apr/memory/unix/apr_pools.c
/* * Allocator * * @note The max_free_index and current_free_index fields are not really * indices, but quantities of BOUNDARY_SIZE big memory blocks. */ struct apr_allocator_t { /** largest used index into free[], always < MAX_INDEX */ apr_uint32_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_uint32_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 */ apr_uint32_t current_free_index; #if APR_HAS_THREADS apr_thread_mutex_t *mutex; #endif /* APR_HAS_THREADS */ 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 *free[MAX_INDEX]; };
参考:
mpm_common - Apache HTTP Server Version 2.4
VMAdmin: Apache MaxMemFree For Lean Memory Control