From: Guilbert STABILO on
Hi all,

I had to port a feeder process from Windows to Solaris.
I did it successfully but then met a huge memory problem at run time.

I explain:

I have to run 12 instances of this same feeder process (each started with
a different command line).
At initialisation time, one instance need 2 GB to initialize then release
the 2 GB.
The instance then have to be up for 24h listening to some network event.
Then the second instance start, eat 2 GB, release the memory and so on
....

At the end, I have 12 instances running concurrently on the same
computer.
This worked fine under Windows but not under Solaris.

In facts, I only succeeded in starting 5 of the 12 instances.
On the 6th one, I get a memory allocation error.
I found that under Solaris (from the "malloc (3C)" manual page), when a
process release some memory, the memory is made available for the process
but not for the system.
Therefore, I have no memory left for the other instances so they can not
start.
I insist on the fact that I have absolutely no memory leaks.

Here is my system (uname -a):

SunOS mssenna01 5.10 Generic_127112-10 i86pc i386 i86pc

... and the available memory (top):

Memory: 4096M phys mem, 3054M free mem, 8001M total swap, 7558M free swap


I think I missed something anyway because such a limitation can not exist
under Unix/Solaris.

* Please tell me if there is a compiler/linker flag which could change
the memory deallocation behavior ?
* Is there another malloc library I could link with which would give the
memory back to the system immediately ?

I precise that I can not change the code because it is composed of many
3rd party libraries so the malloc libraries must expose the same
interfaces.

Thanks in advance for your help.


Here is the source code which exactly simulate my problem with the result
log:

http://webpollux.free.fr/public/testmlk/testmlk.tar
http://webpollux.free.fr/public/testmlk/testmlk.log


Here is the text copy of the code and the log:

============================= testmlk.cpp ===========================
#include <iostream>
using namespace std;
#include <unistd.h>

void testmlk()
{
pid_t pid = getpid();
char szPID[10];
sprintf(szPID, "%u", pid);
string sPsCmd = "ps -ef -opid -ofname -ovsz | grep " + string
(szPID);

char *pszTest = NULL;
cerr << "\nInit: ";
system(sPsCmd.data());

cerr << "Allocating 2000 MB: ";
pszTest = new char [2000000000];
system(sPsCmd.data());

cerr << "Unallocating 2000 MB: ";

if(NULL != pszTest)
{
delete [] pszTest;
pszTest = NULL;
}

else
{
cerr << "Allocation error !" << endl;
}

system(sPsCmd.data());
}



int main(int iArgc, char **ppArgv)
{
testmlk();
cerr << endl;
sleep(200);
cerr << "Exiting ..." << endl;
return(0);
}

============================= testmlk.cpp ===========================


============================= testmlk.log ===========================
** Run 1 **

Init: 23101 testmlk 2192
Allocating 2000 MB: 23101 testmlk 1955320
Unallocating 2000 MB: 23101 testmlk 1955320

** Run 2 **

Init: 23113 testmlk 2192
Allocating 2000 MB: 23113 testmlk 1955320
Unallocating 2000 MB: 23113 testmlk 1955320

** Run 3 **

Init: 23125 testmlk 2192
Allocating 2000 MB: 23125 testmlk 1955320
Unallocating 2000 MB: 23125 testmlk 1955320

** Run 4 **

Init: 23137 testmlk 2192
Allocating 2000 MB: 23137 testmlk 1955320
Unallocating 2000 MB: 23137 testmlk 1955320

** Run 5 **

Init: 23149 testmlk 2192
Allocating 2000 MB: 23149 testmlk 1955320
Unallocating 2000 MB: 23149 testmlk 1955320

** Run 6 **

Init: 23161 testmlk 2192
Allocating 2000 MB: terminate called after throwing an instance of
'std::bad_alloc'
what(): St9bad_alloc
============================= testmlk.log ===========================



From: hume.spamfilter on
Guilbert STABILO <guilbert.stabilo(a)yahoo.fr> wrote:
> The instance then have to be up for 24h listening to some network event.
> Then the second instance start, eat 2 GB, release the memory and so on
> ...

http://www.steve.org.uk/Reference/Unix/faq_2.html#SEC21

.... and:

http://stackoverflow.com/questions/236001/unix-vs-windows-memory-deallocation

--
Brandon Hume - hume -> BOFH.Ca, http://WWW.BOFH.Ca/
From: Guilbert STABILO on
On Oct 21, 11:33 pm, hume.spamfil...(a)bofh.ca wrote:

> http://www.steve.org.uk/Reference/Unix/faq_2.html#SEC21
>
> ... and:
>
> http://stackoverflow.com/questions/236001/unix-vs-windows-memory-deal...

Thanks for these good links which make me understand that I am in a
deadlock.
I have to port my application from Windows to Solaris but I can't
because the Solaris memory management model does not leave enough
memory to the OS for this.
The links are talking about "mmap" but it seems I have to change my
code which is not possible because many parts of the code are not
mine.
My problem is I need huge amount of memory for a very little time and
I have to find a way to give it back to the system otherwise I will
have to stay on Windows.

* Does anybody know a way to link with some different run-time library
which would implicitely use "mmap" instead of the standard method ?

Thanks in advance.


From: Guilbert STABILO on
On Oct 22, 10:00 am, Michael Vilain <vil...(a)NOspamcop.net> wrote:

> You'll have to rethink your approach to use a mmap'ed file rather than a
> large malloc.  There's just no way around this.  If you don't have
> access to all the parts of the code to the application, you'll have to
> write those parts also.  A full redesign.

OK, thanks for confirming.
I expected there should be a way to link with a different C run-time
library (which would manage the memory like Windows does) but
apparently not.
Consequently, this is just impossible for me because my process link
with commercial libraries (for which of course I haven't the source
code) and I have no choice but using them. The bad thing is my memory
issue occurs in those libraries.

This is the first time I find such a limitation on Unix systems.
I am surprised I did not notice this before but this is probably
because this is the first time I work with huge amount of data.
The only choice I have is going back to Windows :-(((

From: Guilbert STABILO on
On Oct 22, 10:38 am, Ian Collins <ian-n...(a)hotmail.com> wrote:

> You could provide your own allocator which passed "normal" sized
> allocations to standard malloc and uses a mapped file for huge ones.

Yes but I have to intercept the malloc which occurs in the commercial
library I am linking with and I am not sure it is possible (I only
have the binary libraries).
My memory issue occurs in those libraries.