diff options
author | sf <sf@13f79535-47bb-0310-9956-ffa450edef68> | 2014-05-14 21:30:48 +0000 |
---|---|---|
committer | sf <sf@13f79535-47bb-0310-9956-ffa450edef68> | 2014-05-14 21:30:48 +0000 |
commit | 2b53ade052014def1455c512fe7d5283fd344bc7 (patch) | |
tree | 454b56ef49820bd0f509719ce61b2577e53f509d /memory/unix/apr_pools.c | |
parent | 968eeaaf7dcfce3141ced68c9a38ee889451e0f8 (diff) | |
download | libapr-2b53ade052014def1455c512fe7d5283fd344bc7.tar.gz |
Don't waste memory when creating or allocating from small, long-lived
APR pools after clearing or destroying pools that allocated larger
nodes.
When allocating nodes from the bucket allocator (<= 80k or 20 pages),
we would eagerly reuse *any* free node that is at least the minimum
size. Depending on the pool usage scheme, that extra memory would
never be used. This patch limits the node to approximate twice the
minimum.
* memory/unix/apr_pools.c
(allocator_alloc): When searching the buckets for free nodes, limit
the range to twice the starting index.
Submitted by: Stefan Fuhrmann <stefan fuhrmann wandisco com>
git-svn-id: http://svn.apache.org/repos/asf/apr/apr/trunk@1594729 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'memory/unix/apr_pools.c')
-rw-r--r-- | memory/unix/apr_pools.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/memory/unix/apr_pools.c b/memory/unix/apr_pools.c index cd4ae112d..da33c78da 100644 --- a/memory/unix/apr_pools.c +++ b/memory/unix/apr_pools.c @@ -239,7 +239,7 @@ static APR_INLINE apr_memnode_t *allocator_alloc(apr_allocator_t *allocator, apr_size_t in_size) { apr_memnode_t *node, **ref; - apr_uint32_t max_index; + apr_uint32_t max_index, upper_index; apr_size_t size, i, index; /* Round up the block size to the next boundary, but always @@ -273,6 +273,11 @@ apr_memnode_t *allocator_alloc(apr_allocator_t *allocator, apr_size_t in_size) /* Walk the free list to see if there are * any nodes on it of the requested size * + * If there is no exact match, look for nodes + * of up to twice the requested size, so we + * won't unnecessarily allocate more memory + * nor waste too much of what we have. + * * NOTE: an optimization would be to check * allocator->free[index] first and if no * node is present, directly use @@ -281,9 +286,10 @@ apr_memnode_t *allocator_alloc(apr_allocator_t *allocator, apr_size_t in_size) * memory waste. */ max_index = allocator->max_index; + upper_index = 2 * index < max_index ? 2 * index : max_index; ref = &allocator->free[index]; i = index; - while (*ref == NULL && i < max_index) { + while (*ref == NULL && i < upper_index) { ref++; i++; } |