HOST MACHINE and OPERATING SYSTEM:
Fedora Core 5
COMPILER NAME AND VERSION (AND PATCHLEVEL):
gcc 4.1.0 20060304 (Red Hat 4.1.0-3)
THE $ACE_ROOT/ace/config.h FILE [if you use a link to a platform-
specific file, simply state which one]:
config-linux.h
THE $ACE_ROOT/include/makeinclude/platform_macros.GNU FILE [if you
use a link to a platform-specific file, simply state which one
(unless this isn't used in this case, e.g., with Microsoft Visual
C++)]:
platform-linux.GNU
DOES THE PROBLEM AFFECT:
COMPILATION?
LINKING?
On Unix systems, did you run make realclean first?
EXECUTION?
OTHER (please specify)?
[Please indicate whether ACE, your application, or both are affected.]
SYNOPSIS:
[Brief description of the problem]
Each activated ACE_Task increases the used memory by ~10 MBytes
DESCRIPTION:
[Detailed description of problem. Don't just say "<blah>
doesn't work, here's a fix," explain what your program does
to get to the <blah> state. ]
In our application we use a lot of ACE_Tasks. As we ran out of memory,
we checked where this came from.
Using top we saw, that each call to activate () on an ACE_Task increased
the memory (column VIRT in top) by ~10MBytes.
Does ACE_Task really consume 10MBytes for each running instance?
Can we somehow decrease this?
REPEAT BY:
Here is a short example. I know that we should join and delete the
tasks, but that is not the problem. The problem is the memory
consumption while it is running.
#include "ace/Task.h"
class C_Task:public ACE_Task<ACE_MT_SYNCH>
{
public:
C_Task (void);
virtual int svc (void);
int close (u_long i);
~C_Task (void);
private:
};
C_Task::C_Task (void)
{
}
C_Task::~C_Task (void)
{
}
int C_Task::close (u_long)
{
delete this;
return 0;
}
int C_Task::svc (void)
{
int i=0;
printf ("C_MethodCaller start\n");
while (1)
{
printf ("loop %d\n", i++);
ACE_OS::sleep (1);
}
printf ("C_MethodCaller end\n");
return 0;
}
int main (int argc, char *argv[])
{
ACE_UNUSED_ARG (argc);
ACE_UNUSED_ARG (argv);
C_Task* pc_Task;
for (int i=0;i<100;i++)
{
pc_Task=new C_Task ();
if (pc_Task->activate (THR_NEW_LWP|THR_JOINABLE)==-1)
{
printf ("error in spawning thread (err_msg: %m)\n");
return -1;
}
}
while (1)
{
}
return EXIT_SUCCESS;
}
SAMPLE FIX/WORKAROUND:
[If available ]
Thanks for using the PRF.
It depends on what the default size of a thread stack is on Linux.
> Can we somehow decrease this?
Sure, you can make the size of the stack as large/small as you want when
you activate() a task. Please see Chapter 6 of C++NPv2
<www.cs.wustl.edu/~schmidt/ACE/book2/> for more detalis.
Thanks,
Doug
> _______________________________________________
> ace-users mailing list
> ace-...@mail.cse.wustl.edu
> http://mail.cse.wustl.edu/mailman/listinfo/ace-users
No. You're misinterpreting the 'top' output. Memory profiling on linux is
not always easy since it uses copy-on-write memory management for fork() and
pthread_create() calls. So even though it claims that it could be using up to
10MB/thread (if copy-on-write and other memory optimizations weren't used),
the actual use is much, much lower. You should be looking at the RES column,
that tells how much memory you're actually using.
Doing a quick test of your program on my box, heres what I get for 100 threads:
VIRT: 1005m RES: 3416
and for 10 threads:
VIRT: 104m RES: 1908
So, going by the RES field, each thread seems to add 150 *Bytes* of actual
memory usage. See this page for more info:
http://gentoo-wiki.com/FAQ_Linux_Memory_Management
> for (int i=0;i<100;i++)
> {
> pc_Task=new C_Task ();
> if (pc_Task->activate (THR_NEW_LWP|THR_JOINABLE)==-1)
> {
> printf ("error in spawning thread (err_msg: %m)\n");
> return -1;
> }
> }
By the way, activate() takes a parameter that tells it how many threads to
spawn, so you could replace the entire for loop above with this:
pc_Task=new C_Task();
int numberOfThreads = 100;
if (pc_Task->activate (THR_NEW_LWP|THR_JOINABLE, numberOfThreads) == -1)
{ ... }
Matt
I tried Dougs hint of explicitly setting the stack size, and it seems to
work.
Oliver
that was exactly the hint I was searching for.
Thank you.
regards,
Oliver
> -----Ursprüngliche Nachricht-----
> Von: sch...@tango.dre.vanderbilt.edu
> [mailto:sch...@tango.dre.vanderbilt.edu] Im Auftrag von
> Douglas C. Schmidt
> Gesendet: Freitag, 22. September 2006 14:51
> An: Spang, Oliver
> Cc: ace-...@cs.wustl.edu
> Betreff: Re: [ace-users] ACE_Task needs a lot of memory
> > In our application we use a lot of ACE_Tasks. As we ran out
> of memory,
> > we checked where this came from.
> > Using top we saw, that each call to activate () on an
> ACE_Task increased
> > the memory (column VIRT in top) by ~10MBytes.
> > Does ACE_Task really consume 10MBytes for each running instance?
>
> > for (int i=0;i<100;i++)
> > {
> > pc_Task=new C_Task ();
> > if (pc_Task->activate (THR_NEW_LWP|THR_JOINABLE)==-1)
> > {
> > printf ("error in spawning thread (err_msg: %m)\n");
> > return -1;
> > }
> > }
> >