You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@celix.apache.org by Thomas Quartier <th...@student.kuleuven.be> on 2014/04/10 14:34:20 UTC

APR memory dealocation when bundle stops

Hello,

 

I'm testing Celix for my master thesis. I've cross compiled Celix to
embedded Linux for an ARM at91sam9260-ek development board using Buildroot.
To test the memory footprint of Celix, I have 10 bundles that each start and
stop an APR thread in the bundleActivator_start and bundleActivator_stop
functions. I start and stop these 10 bundles one by one. In the memory plot,
I can see all bundles start but when stopping them, memory is not
deallocated. To stop a thread, I set a bool to false and wait (join) for the
thread to exit as in the echo example. The execution of the thread and the
bundle stops but memory stays allocated. I also tried to use the
apr_thread_exit function after the join but that results in a segmentation
fault.

 

 

Kind regards,

Thomas

 

 


RE: APR memory dealocation when bundle stops

Posted by Thomas Quartier <th...@student.kuleuven.be>.
Hi,

Hi, until yesterday, I only measured the memory with memstat (measuring the
virtual memory size). I also did the test on an x86 system and the result is
the same.

When I stop a bundle and start it again, the memory doesn't grow. The pool
is reused.

I now also measured the physical memory used by celix and the result is
better, memory gets allocated when a bundle starts and a part of that is
deallocated when a bundles stops. There is a part of the physical memory
that doesn't return to the operating system when a bundle stops.
Below is the output of the free command (used memory in kB) when I start and
stop 10 identical bundles on an ARM board.

Watch -n 1 'free >> memory.txt'

7800
7784
7784
7800
7800
7800
7800
7800
9076 --> start Celix framework
9076
9076
9076
9060
9060
9060
9060
9060
9060
9060
9072
9072
9072
9072
9072
9072
9520 --> start 10 bundles
9624
9612
9612
9612
9612
9612
9624
9624
9624
9624
9608
9608
9608
9608
9608
9608
9608
9608
9608
9608
9608
9608
9608
9620
9620
9620
9620
9620
9620
9620
9620
9620
9620
9620
9620
9620
9620
9620
9620
9620
9620
9636
9636
9636
9636
9636
9636
9636
9620
9620
9620
9620
9620
9620
9620
9620
9620
9620
9620
9620
9620
9620
9632
9632
9632
9632
9632
9632
9632
9632
9632
9632
9632
9632
9632
9644
9644
9660
9660
9660
9660
9660
9660
9644
9636
9616
9600
9572
9532
9480 --> stop 10 bundles
9480
9480
9480
9480
9480
9480
9480
9480
9480
9480
9480
9480
9480
9480
9480
9480
9496
9496
9496
9496
9496
9480
9480
9480
9480
9480
9480
9480
9480
9480
9480
9480
9480
9480
9480
9480
9492
9492
9492
9492
9492
9492
9492
9492
9492
9492
9508
9508
9508
9508
9508
9508
9492
9492
9492
9492
9492
9492
9492
9492
9492
9492
9492
9492
9492
9492
9492
9492
9492
9492
9492
9492
9492
9492
9492
9504
9520
9520
9520
9520
9520
9520
9520
9504
9504
9504
9504
9504
9504
9504
9504
9504
9504
9504
9504
9504
9504
9504
9504
9504
9504
9504
9504
9504
9504
9504
9520
9520
9520
9520
9504
9504
9504
9516
9516
9516
9516
9516
9516
9516
9516
9516
9516
9536
9536
9512
7928 --> stop Celix framework
7928
7928
7916
7916
7916
7916
7916 

Kind regards,
Thomas





Re: APR memory dealocation when bundle stops

Posted by Alexander Broekhuis <a....@gmail.com>.
Hi,

Thanks for the code, at first test I can't find anything strange with it.

Some more questions/thoughs
- Did you also do the same test on a x86 system? Just wondering if it might
be the cross compilations.
- If you stop a bundle, and start it again, does the memory grow? Or does
it reuse the memory and are you perhaps seeing a side-effect of the pool
where it doesn't release immediately (I am not sure on this one, and find
it difficult to debug APR in these instances, but maybe this has also to do
with the fact that I am using OSX).

Looking at the flow of the code, the context pool is created when the
bundles is started, and destroyed when the bundle is stopped.

I am not sure how long you are following the list, but a while ago I
started a discussion about the usage of APR [1]. Any thoughts on the topic
are still welcome. At this moment I feel Celix would benefit when APR was
taken out, but then again, this is quite a big job, so we didn't do
anything yet.

I'll look a bit more into it, any other ideas are welcome as well.

[1]: http://incubator.markmail.org/thread/wmyas74a3fhxorhu


2014-04-10 16:18 GMT+02:00 Thomas Quartier <
thomas.quartier@student.kuleuven.be>:

> Hi,
>
> This is my code:
>
> #include <stdlib.h>
> #include <stdio.h>
> #include <unistd.h>
> #include <sys/time.h>
>
> #include <apr_general.h>
>
> #include "bundle_activator.h"
> #include "bundle_context.h"
> #include "service_tracker.h"
>
> #include <sys/wait.h>
> #include <sys/mman.h>
>
> struct activator_data {
>         bool running;
>         apr_pool_t *pool;
>         apr_thread_t *sender;
> };
>
> typedef struct activator_data * activator_data_pt;
>
> static void *APR_THREAD_FUNC my_thread_func(apr_thread_t *thd, void *data)
> {
>         int i = 0;
>         int j = 0;
>         activator_data_pt act = (activator_data_pt) data;
>         while (act->running) {
>                 printf("my_thread_for_1\n");
>                 j = 0;
>                 for(i = 0; i<=10000; i++){
>                         j+=rand();
>                 }
>                 printf("my_thread_for_1: for until %i\n", j);
>                 apr_sleep(1000000);
>         }
>         apr_thread_exit(thd, APR_SUCCESS);
>         return NULL;
> }
>
> celix_status_t bundleActivator_create(bundle_context_pt context, void
> **userData) {
>         apr_pool_t *pool;
>         celix_status_t status = bundleContext_getMemoryPool(context,
> &pool);
>         if (status == CELIX_SUCCESS) {
>                 *userData = apr_palloc(pool, sizeof(struct
> activator_data));
>                 ((activator_data_pt)(*userData))->running = false;
>                 ((activator_data_pt)(*userData))->pool = NULL;
>                 ((activator_data_pt)(*userData))->sender = NULL;
>         } else {
>                 status = CELIX_START_ERROR;
>         }
>         return CELIX_SUCCESS;
> }
>
> celix_status_t bundleActivator_start(void * userData, bundle_context_pt
> context) {
>         activator_data_pt act = (activator_data_pt) userData;
>         apr_pool_t *pool = NULL;
>         bundleContext_getMemoryPool(context, &pool);
>         act->pool=pool;
>         act->running=true;
>         apr_thread_create(&act->sender, NULL, my_thread_func, act,
> act->pool);
>         return CELIX_SUCCESS;
> }
>
> celix_status_t bundleActivator_stop(void * userData, bundle_context_pt
> context) {
>         apr_status_t aprStatusT = 0;
>         activator_data_pt act = (activator_data_pt) userData;
>         apr_status_t status;
>         act->running=false;
>         apr_thread_join(&status, act->sender);
>         return CELIX_SUCCESS;
> }
>
> celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt
> context) {
>         activator_data_pt act = (activator_data_pt) userData;
>         act->sender = 0;
>         act = NULL;
>         return CELIX_SUCCESS;
> }
>
> Kind regards,
> Thomas
>
> -----Original Message-----
> From: Alexander Broekhuis [mailto:a.broekhuis@gmail.com]
> Sent: donderdag 10 april 2014 15:55
> To: celix-dev@incubator.apache.org
> Subject: Re: APR memory dealocation when bundle stops
>
> Hello,
>
> Could you send me an example of the code? I'll try to look into it and see
> whats going on.
>
>
> 2014-04-10 14:34 GMT+02:00 Thomas Quartier <
> thomas.quartier@student.kuleuven.be>:
>
> > Hello,
> >
> >
> >
> > I'm testing Celix for my master thesis. I've cross compiled Celix to
> > embedded Linux for an ARM at91sam9260-ek development board using
> Buildroot.
> > To test the memory footprint of Celix, I have 10 bundles that each
> > start and stop an APR thread in the bundleActivator_start and
> > bundleActivator_stop functions. I start and stop these 10 bundles one
> > by one. In the memory plot, I can see all bundles start but when
> > stopping them, memory is not deallocated. To stop a thread, I set a
> > bool to false and wait (join) for the thread to exit as in the echo
> > example. The execution of the thread and the bundle stops but memory
> > stays allocated. I also tried to use the apr_thread_exit function
> > after the join but that results in a segmentation fault.
> >
> >
> >
> >
> >
> > Kind regards,
> >
> > Thomas
> >
> >
> >
> >
> >
> >
>
>
> --
> Met vriendelijke groet,
>
> Alexander Broekhuis
>
>


-- 
Met vriendelijke groet,

Alexander Broekhuis

RE: APR memory dealocation when bundle stops

Posted by Thomas Quartier <th...@student.kuleuven.be>.
Hi,

This is my code:

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>

#include <apr_general.h>

#include "bundle_activator.h"
#include "bundle_context.h"
#include "service_tracker.h"

#include <sys/wait.h>
#include <sys/mman.h>

struct activator_data {
	bool running;
	apr_pool_t *pool;
	apr_thread_t *sender;
};

typedef struct activator_data * activator_data_pt;

static void *APR_THREAD_FUNC my_thread_func(apr_thread_t *thd, void *data) {
	int i = 0;
	int j = 0;
	activator_data_pt act = (activator_data_pt) data;
	while (act->running) {
		printf("my_thread_for_1\n"); 
		j = 0;
		for(i = 0; i<=10000; i++){ 
			j+=rand();
		}
		printf("my_thread_for_1: for until %i\n", j);
		apr_sleep(1000000);
	}
	apr_thread_exit(thd, APR_SUCCESS);
	return NULL;
}

celix_status_t bundleActivator_create(bundle_context_pt context, void
**userData) {
	apr_pool_t *pool;
	celix_status_t status = bundleContext_getMemoryPool(context, &pool);
	if (status == CELIX_SUCCESS) {
		*userData = apr_palloc(pool, sizeof(struct activator_data));
		((activator_data_pt)(*userData))->running = false;
		((activator_data_pt)(*userData))->pool = NULL;
		((activator_data_pt)(*userData))->sender = NULL;
	} else {
		status = CELIX_START_ERROR;
	}
	return CELIX_SUCCESS;
}

celix_status_t bundleActivator_start(void * userData, bundle_context_pt
context) {
	activator_data_pt act = (activator_data_pt) userData;
	apr_pool_t *pool = NULL;
	bundleContext_getMemoryPool(context, &pool);
	act->pool=pool;
	act->running=true;
	apr_thread_create(&act->sender, NULL, my_thread_func, act,
act->pool);
	return CELIX_SUCCESS;
}

celix_status_t bundleActivator_stop(void * userData, bundle_context_pt
context) {
	apr_status_t aprStatusT = 0;
	activator_data_pt act = (activator_data_pt) userData;
	apr_status_t status;
	act->running=false;
	apr_thread_join(&status, act->sender);
	return CELIX_SUCCESS;
}

celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt
context) {
	activator_data_pt act = (activator_data_pt) userData;
	act->sender = 0;
	act = NULL;
	return CELIX_SUCCESS;
}

Kind regards,
Thomas

-----Original Message-----
From: Alexander Broekhuis [mailto:a.broekhuis@gmail.com] 
Sent: donderdag 10 april 2014 15:55
To: celix-dev@incubator.apache.org
Subject: Re: APR memory dealocation when bundle stops

Hello,

Could you send me an example of the code? I'll try to look into it and see
whats going on.


2014-04-10 14:34 GMT+02:00 Thomas Quartier <
thomas.quartier@student.kuleuven.be>:

> Hello,
>
>
>
> I'm testing Celix for my master thesis. I've cross compiled Celix to 
> embedded Linux for an ARM at91sam9260-ek development board using
Buildroot.
> To test the memory footprint of Celix, I have 10 bundles that each 
> start and stop an APR thread in the bundleActivator_start and 
> bundleActivator_stop functions. I start and stop these 10 bundles one 
> by one. In the memory plot, I can see all bundles start but when 
> stopping them, memory is not deallocated. To stop a thread, I set a 
> bool to false and wait (join) for the thread to exit as in the echo 
> example. The execution of the thread and the bundle stops but memory 
> stays allocated. I also tried to use the apr_thread_exit function 
> after the join but that results in a segmentation fault.
>
>
>
>
>
> Kind regards,
>
> Thomas
>
>
>
>
>
>


--
Met vriendelijke groet,

Alexander Broekhuis


Re: APR memory dealocation when bundle stops

Posted by Alexander Broekhuis <a....@gmail.com>.
Hello,

Could you send me an example of the code? I'll try to look into it and see
whats going on.


2014-04-10 14:34 GMT+02:00 Thomas Quartier <
thomas.quartier@student.kuleuven.be>:

> Hello,
>
>
>
> I'm testing Celix for my master thesis. I've cross compiled Celix to
> embedded Linux for an ARM at91sam9260-ek development board using Buildroot.
> To test the memory footprint of Celix, I have 10 bundles that each start
> and
> stop an APR thread in the bundleActivator_start and bundleActivator_stop
> functions. I start and stop these 10 bundles one by one. In the memory
> plot,
> I can see all bundles start but when stopping them, memory is not
> deallocated. To stop a thread, I set a bool to false and wait (join) for
> the
> thread to exit as in the echo example. The execution of the thread and the
> bundle stops but memory stays allocated. I also tried to use the
> apr_thread_exit function after the join but that results in a segmentation
> fault.
>
>
>
>
>
> Kind regards,
>
> Thomas
>
>
>
>
>
>


-- 
Met vriendelijke groet,

Alexander Broekhuis