You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Jean-Jacques Clar <JJ...@novell.com> on 2002/10/07 19:19:05 UTC
MaxMemFree implementation
I have been trying to understand why MaxMemFree is not working as
I am expecting it to in our MPM (NetWare).
I am getting to the conclusion that either the memory allocation in our
MPM
is missing a piece or there is a missing function in the apr_bucket
set.
I think this is relevant to other MPMs.
Each thread is initialized using the following calls:
apr_allocator_create(&allocator);
apr_allocator_max_free_set(allocator, ap_max_mem_free);
apr_pool_create_ex(&ptrans, NULL, NULL, allocator);
apr_allocator_owner_set(allocator, ptrans);
apr_pool_tag(ptrans, "transaction");
bucket_alloc = apr_bucket_alloc_create(pmain);
the transaction pool is then cleared after processing every
connection.
Most of the memory storage allocated is used by buckets while
caching/refreshing large
files for the memory caching modules (output filter).
Buckets memory is correctly returned using:
apr_brigade_destroy() -> apr_brigade_cleanup() then calling
apr_bucket_delete()
for each bucket in the brigade.
In apr_bucket_free, because the size of the nodes used are mostly
bigger than SMALL_NODE_SIZE,
apr_allocator_free is called passing as a parameter
the allocator field from the bucket_alloc structure created using:
bucket_alloc = apr_bucket_alloc_create(pmain);
struct apr_bucket_alloc_t {
apr_pool_t *pool;
apr_allocator_t *allocator;
node_header_t *freelist;
apr_memnode_t *blocks;
};
The problem is right there: the allocator field of the
apr_bucket_alloc_t struct is used to
alloc and free buckets. I did not find any way to set the
max_free_index on that field.
Am I missing something?
Using the following new function in apr_buckets_alloc.c, it includes a
size parameter and a call
to apr_allocator_free(), works a lot better for me.
Using a small MaxMemFree directive, the memory allocation for APRLIB
is down around 50 MB
instead of the previous 250MB.
bucket_alloc = apr_bucket_alloc_create(pmain, ap_max_mem_free);
APU_DECLARE_NONSTD(apr_bucket_alloc_t *)
apr_bucket_alloc_create_set_max_free(apr_pool_t *p, apr_size_t size)
{
apr_allocator_t *allocator;
apr_bucket_alloc_t *list;
apr_memnode_t *block;
apr_allocator_create(&allocator);
block = apr_allocator_alloc(allocator, ALLOC_AMT);
list = (apr_bucket_alloc_t *)block->first_avail;
list->pool = p;
list->allocator = allocator;
list->freelist = NULL;
list->blocks = block;
block->first_avail += APR_ALIGN_DEFAULT(sizeof(*list));
apr_allocator_max_free_set(list->allocator, size);
apr_pool_cleanup_register(list->pool, list, alloc_cleanup,
apr_pool_cleanup_null);
return list;
}
Am I following a wrong direction or this should be implemented to limit
memory usage
in case like mine?
Thanks,
JJ
Re: MaxMemFree implementation
Posted by Cliff Woolley <jw...@virginia.edu>.
On Mon, 7 Oct 2002, Jean-Jacques Clar wrote:
>
> Am I following a wrong direction or this should be implemented to limit
> memory usage
> in case like mine?
Yes, that's on my list of things to work on soonish.
--Cliff