Drexel dragonThe Math ForumDonate to the Math Forum



Search All of the Math Forum:

Views expressed in these public forums are not endorsed by Drexel University or The Math Forum.


Math Forum » Discussions » Software » comp.soft-sys.matlab

Topic: matlab/mex function doesn't free memory
Replies: 22   Last Post: Dec 10, 2012 1:49 AM

Advanced Search

Back to Topic List Back to Topic List Jump to Tree View Jump to Tree View   Messages: [ Previous | Next ]
Praetorian

Posts: 727
Registered: 1/25/05
Re: matlab/mex function doesn't free memory
Posted: Apr 9, 2009 1:23 PM
  Click to see the message monospaced in plain text Plain Text   Click to reply to this topic Reply

On Apr 8, 9:20 pm, "James Tursa" <aclassyguywithakno...@hotmail.com>
wrote:
> Praetorian <ashish.sadanan...@gmail.com> wrote in message <251c8005-d072-419f-ad9a-28680bdb1...@g19g2000yql.googlegroups.com>...
>

> > James,
> > I was hoping you'd see this thread. Take a look at the post from Ronan
> > on the 4th of February. It was directed to me but I didn't see it
> > until last night. Do you have any experience with calling a DLL that
> > uses the mxCreate* functions to allocate memory? And does the MATLAB
> > memory manager garbage collect that memory assuming that the DLL is
> > loaded and used by a mex file?

>
> > Regards,
> > Ashish.

>
> Well, I didn't have any experience with this when I first read this post, but now I do.  The answer is no, MATLAB does *not* do garbage collection on mx___ allocated memory in a loaded dll. This is different from mex functions, where garbage collection *is* done.  Example files are below.  Commands I used to show the memory leak are:
>
> mex mexmem.c
> mexmem
> feature memstats
>
> This will show the garbage collection being done for mex functions. Inside the function, 100MB is allocated but not explicitly deallocated. The feature memstats done inside the mex routine show the allocation. But upon returning to MATLAB and doing a feature memstats reveals that the memory is in fact freed.
>
> Now build the dllmem dll (I used a mex command with a custom mexopts.bat file to build the dll library) and then do this:
>
> loadlibrary('dllmem.mexw32','dllmem.h')
> feature memstats
> calllib('dllmem','memallocate')
> feature memstats
> unloadlibrary('dllmem')
> feature memstats
>
> You can see that the 100MB has been leaked. Garbage collection did *not* take place when the dll library was unloaded.
>
> Bottom line: Free the memory manually, no safety net here.
>
> James Tursa
>
> --------------------------------------------------------------------------------------------------
> mexmem.c
>
> #include "mex.h"
>
> double *dp = NULL;
>
> void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
> {
>     mexEvalString("feature memstats");
>     if( dp == NULL ) {
>         dp = mxMalloc(13107200*sizeof(double));  // allocate 100MB
>     }
>     mexEvalString("feature memstats");
>
> }
>
> -------------------------------------------------------------------------------------------------------
> dllmem.c
>
> #include "mex.h"
>
> double *dp = NULL;
>
> void memallocate(void)
> {
>     if( dp == NULL ) {
>         dp = mxMalloc(13107200*sizeof(double));  // allocate 100MB
>     }
>
> }
>
> void memdeallocate(void)
> {
>     if( dp ) {
>         mxFree(dp);
>     }
>     dp = NULL;
>
> }
>
> -----------------------------------------------------------------------------------------------------
> dllmem.h
>
> void memallocate(void);
> void memdeallocate(void);
>
> ----------------------------------------------------------------------------------------------------
> dllmem.def
>
> EXPORTS
> memallocate
> memdeallocate



Thanks for coding up that example! So I went ahead and did things a
little differently; instead of using CALLLIB from the command line I
loaded the DLL using the Windows API LoadLibrary function from within
mexmem. And what do you know, MATLAB garbage collects the memory in
that case. The only other difference was that I created a Visual
Studio project to compile my DLL instead of modifying mexopts.bat but
I can't think of any project setting that would cause this change in
behavior. Here's my modified mexmem.c


------------------------------------------------------------------------------------------------------
mexmem.c


#include "mex.h"
#include "windows.h"

double *dp = NULL;

/* mexmem - allocates memory within mexFunction, does not
free it
* mexmem( false ) - same as first call
* mexmem( true ) - calls dllmem.dll which allocates memory, does
not free it
* mexmem( true, ... ) - calls dllmem.dll which deallocates memory
*/

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray
*prhs[])
{
mexEvalString("feature memstats");
if( ( nrhs == 0 ) || ( !mxIsLogicalScalarTrue(prhs[0]) ) ) {
if( dp == NULL ) {
dp = mxMalloc(100*1024*1024*sizeof(double)); //100MB * sizeof
(double)
mexPrintf( "Memory allocated at: %px\n", dp );
} else {
mexPrintf( "Memory not allocated\n" );
}
} else {
HMODULE hLib = LoadLibrary( "dllmem.dll" );

mexPrintf( "Loading dllmem\n" );

if( hLib == NULL ) {
mexPrintf( "Failed to load dllmem" );
} else {
FARPROC pAlloc = GetProcAddress( hLib, "memallocate" );
FARPROC pDealloc = GetProcAddress( hLib, "memdeallocate" );

if( pAlloc == NULL ) {
mexPrintf( "Failed to get memallocate address" );
} else if( pDealloc == NULL ) {
mexPrintf( "Failed to get memdeallocate address" );
}

if( nrhs > 1 ) {
(pDealloc)();
} else {
(pAlloc)();
}

if( FreeLibrary( hLib ) == 0 ) {
mexPrintf( "Failed to unload dllmem" );
}
}
}

mexEvalString("feature memstats");
}
------------------------------------------------------------------------------------

The calls I made at the command line were:

%To test allocation within mexmem
mexmem
feature memstats
[x x] = inmem;
any(ismember('mexmem', x))

%To test allocation within dllmem
mexmem( true )
feature memstats
[x x] = inmem;
any(ismember('mexmem', x))

I added the INMEM check because I was always under the impression that
MATLAB didn't do any mex garbage collection until the mex file was
cleared from memory. But these tests prove otherwise! Also, I tried
commenting out the FreeLibrary call to see what would happen if the
DLL remained in memory but that gave the same results.

Any thoughts on why CALLLIB doesn't work the same way?

Regards,
Ashish.



Point your RSS reader here for a feed of the latest messages in this topic.

[Privacy Policy] [Terms of Use]

© Drexel University 1994-2014. All Rights Reserved.
The Math Forum is a research and educational enterprise of the Drexel University School of Education.