Info

This question is closed. Reopen it to edit or answer.

Matlab program continual decrease in computer memory

1 view (last 30 days)
steve
steve on 14 Jan 2015
Closed: MATLAB Answer Bot on 20 Aug 2021
Hi All-
I ran a program over the weekend that had a few embedded for loops that was calling a mex function repeatedly. One major problem was that the MAC I am running it on was throwing me memory warnings that I was running out of harddrive space. I opened Activity Monitor and under Disk Usage, I had only a few MBs of memory remaining.
I notice running a similar program that each time I call, I can watch the free memory decrease and decrease. When I totally close out matlab, then it frees all of the memory that the program had used and I am back to where I started.
I am not sure where the 'memory leak is' per say, but my most basic question is where is all of that memory going? What is being stored or allocated? How can I free it within the matlab program space? I am effectively repeating the same loop again and again.
Any help would be appreciated and I can post code if that is helpful.
Update:
Alright, after a little more investigation, I suspect I am not deallocating properly in the mex file I am running.
Frankly, I have found that to be very confusing! It is not clear to me if I need to deallocate the arrays? Or the pointers? Or both? Could someone explain or tell me how to deallocate the fortran code properly? This methodology follows very closely from: http://www.mathworks.com/help/matlab/matlab_external/create-fortran-source-mex-file.html
Also, you will notice a bunch of call mxFree(ptr), which did not appear to be working when I tried to compile the mex function.
C added the scale factor variable
#include "fintrf.h"
subroutine mexfunction(nlhs, plhs, nrhs, prhs)
C-----------------------------------------------------------------------
C DEFINE VARIABLES
C These are variables needed by matlab to run the mex file
C plhs = pointer left hand side of function - output
C prhs = pointer right hand side of funct -- input
mwPointer plhs(*), prhs(*)
integer nlhs, nrhs
C DECLARE FUNCTIONS POINT TO FUNCTIONS WE NEED
mwPointer mxCreateDoubleMatrix, mxGetPr
mwPointer mxFree
C DECLARE LOCAL VARIABLES
C input pointers
mwPointer w_ptr,rusU_ptr,zNeM_ptr,Cf_ptr
mwPointer CfS_ptr, FS_ptr,FC_ptr,SF_ptr
mwPointer Bx_ptr,By_ptr,Bz_ptr,hmF_ptr
mwPointer Amp_ptr
C output pointers
mwPointer r_ptr,th_ptr,ph_ptr,h_ptr,wlen_ptr
mwPointer glon_ptr, glat_ptr, parout_ptr
mwPointer mrows, ncols
mwSize size
real*8 w(400), R(10000),TH(10000),PH(10000)
real*8 H(10000),GLON(10000),GLAT(10000)
REAL*8 RusU(4201,8),zNeM(4201)
REAL*8 BX,BY,BZ,AmpScale,Bmag2,Cf(6,8),CfS(6,8)
real*8 FS(4,4), FC(4,4), SF(8),hmF, Bmag,wlen
C data FS/16 * 0.0/
C data FC/16 * 0.0/
C data R/5000 * 0.0/, TH/5000*0.0/,PH/5000*0.0/
C data H/5000*0.0/, GLON/5000*0.0/,GLAT/5000*0.0/
COMMON /RU/ RusU
COMMON /RNEM/ zNeM
COMMON /RCF/ Cf
COMMON /RCFS/ CfS
COMMON /RFS/ FS
COMMON /RFC/ FC
COMMON /RSF/ SF
common /RIC/ BX,BY,BZ,hmF,AmpScale,wlen
real*8 PAROUT(16)
C-----------------------------------------------------------------------
C CHECK FOR PROPER NUMBER OF ARGUMENTS
C
C wlen=1000.
if (nrhs .ne. 14) then
call mexErrMsgTxt('Need 14 input Argument - W array')
elseif (nlhs .ne. 7) then
call mexErrMsgTxt('Need 7 output arguments')
endif
C open(unit=19,file='./diagnostic/Mex_FillArr.txt')
C open(unit=16,file='./diagnostic/Mex_NeFunct.txt')
C This will clear the matrices so previous values aren't included
do i=1, 10000
R(i) = 0.
H(i) = 0.
TH(i) = 0.
PH(i) =0.
GLON(i) =0.
GLAT(i) =0.
enddo
do i=1,16
parout(i) =0.
enddo
C Read in W_array
C Point to the input matrix
w_ptr = mxGetPr(prhs(1))
C Determine the size of the input matrix
mrows = mxGetM(prhs(1))
ncols = mxGetN(prhs(1))
size = mrows*ncols
call mxCopyPtrToReal8(w_ptr,w,size)
C now rinse and repeat for the other matrices
rusU_ptr = mxGetPr(prhs(2))
mrows = mxGetM(prhs(2))
ncols = mxGetN(prhs(2))
size = mrows*ncols
call mxCopyPtrToReal8(rusU_ptr,RusU,size)
C write(19,*), RusU
zNeM_ptr = mxGetPr(prhs(3))
mrows = mxGetM(prhs(3))
ncols = mxGetN(prhs(3))
size = mrows*ncols
call mxCopyPtrToReal8(zNeM_ptr,zNeM,size)
Cf_ptr = mxGetPr(prhs(4))
mrows = mxGetM(prhs(4))
ncols = mxGetN(prhs(4))
size = mrows*ncols
call mxCopyPtrToReal8(Cf_ptr,Cf,size)
CfS_ptr = mxGetPr(prhs(5))
mrows = mxGetM(prhs(5))
ncols = mxGetN(prhs(5))
size = mrows*ncols
call mxCopyPtrToReal8(CfS_ptr,CfS,size)
FC_ptr = mxGetPr(prhs(6))
mrows = mxGetM(prhs(6))
ncols = mxGetN(prhs(6))
size = mrows*ncols
call mxCopyPtrToReal8(FC_ptr,FC,size)
FS_ptr = mxGetPr(prhs(7))
mrows = mxGetM(prhs(7))
ncols = mxGetN(prhs(7))
size = mrows*ncols
call mxCopyPtrToReal8(FS_ptr,FS,size)
C Non Arrays
Bx_ptr = mxGetPr(prhs(8))
call mxCopyPtrToReal8(Bx_ptr,BX,1)
By_ptr = mxGetPr(prhs(9))
call mxCopyPtrToReal8(By_ptr,BY,1)
Bz_ptr = mxGetPr(prhs(10))
call mxCopyPtrToReal8(Bz_ptr,BZ,1)
hmF_ptr = mxGetPr(prhs(11))
call mxCopyPtrToReal8(hmF_ptr,hmF,1)
Amp_ptr = mxGetPr(prhs(12))
call mxCopyPtrToReal8(Amp_ptr,AmpScale,1)
wlen_ptr = mxGetPr(prhs(13))
call mxCopyPtrToReal8(wlen_ptr,wlen,1)
C added on 12-29-2014 because I forgot it initiall
C these are the scale factor variables
SF_ptr = mxGetPr(prhs(14))
mrows = mxGetM(prhs(14))
ncols = mxGetN(prhs(14))
size = mrows*ncols
call mxCopyPtrToReal8(SF_ptr,SF,size)
C Create Fortran array from the input argument. 'map the pointer'
C Create Output array
C Create matrix for the return argument.
plhs(1) = mxCreateDoubleMatrix(10000,1,0)
plhs(2) = mxCreateDoubleMatrix(10000,1,0)
plhs(3) = mxCreateDoubleMatrix(10000,1,0)
plhs(4) = mxCreateDoubleMatrix(10000,1,0)
plhs(5) = mxCreateDoubleMatrix(10000,1,0)
plhs(6) = mxCreateDoubleMatrix(10000,1,0)
plhs(7) = mxCreateDoubleMatrix(16,1,0)
C Use the mxGetPr function to assign the y_ptr argument to plhs(1).
r_ptr = mxGetPr(plhs(1))
th_ptr = mxGetPr(plhs(2))
ph_ptr = mxGetPr(plhs(3))
h_ptr = mxGetPr(plhs(4))
glon_ptr =mxGetPr(plhs(5))
glat_ptr = mxGetPr(plhs(6))
parout_ptr = mxGetPr(plhs(7))
CPass the arguments to timestwo.
C Call the computational subroutine.
call JONES(W,R,TH,PH,H,GLON,GLAT,PAROUT)
C print*, R
C call mxCopyReal8ToPtr(y_output,y_ptr,size) Ccopy to output pointer
call mxCopyReal8ToPtr(R,r_ptr,10000)
call mxCopyReal8ToPtr(TH,th_ptr,10000)
call mxCopyReal8ToPtr(PH,ph_ptr,10000)
call mxCopyReal8ToPtr(H,h_ptr,10000)
call mxCopyReal8ToPtr(GLON,glon_ptr,10000)
call mxCopyReal8ToPtr(GLAT,glat_ptr,10000)
call mxCopyReal8ToPtr(PAROUT,parout_ptr,16)
C 01142015
C now do a bunch of memory clean up
C call mxFree(rusU_ptr)
C call mxFree(zNeM_ptr)
C call mxFree(Cf_ptr)
C call mxFree(CfS_ptr)
C call mxFree(FS_ptr)
C call mxFree(FC_ptr)
C call mxFree(SF_ptr)
C call mxFree(Bx_ptr)
C call mxFree(By_ptr)
C call mxFree(Bz_ptr)
C call mxFree(hmF_ptr)
C call mxFree(Amp_ptr)
C call mxDestroyArray(plhs(1))
C call mxFree(r_ptr)
C call mxFree(th_ptr)
C call mxFree(ph_ptr)
C call mxFree(h_ptr)
C call mxFree(wlen_ptr)
C call mxFree(glon_ptr)
C call mxFree(glat_ptr), parout_ptr
C do i=1,14
C write(19,*), PAROUT(i)
C enddo
C
C
C
C close(16)
C close(19)
return
call mxDestroyArray(plhs(1))
mxFree(w_ptr)
C call mxDestroyArray(H)
C call mxDestroyArray(plhs(4))
end
As a final comment, I feel that the documentation is contradictory. I wrote this based on the example I stated in the link above and in reading about the left hand side arguments, you do not call a destroy command if you are exporting an array - like what I think I am doing. However, then you run into a memory leak!
Anyway, I am totally confused, please help.
  1 Comment
dpb
dpb on 14 Jan 2015
No way to know in general. The first idea would be that since a mex file is in play is that it isn't releasing its memory on completion.
You'll have to "divide and conquer" and isolate which pieces of the process are the culprit.
It's possible if you post the mex code somebody can see a flaw if it's an obvious one but that's certainly not guaranteed to happen quickly if it is a more subtle problem.

Answers (0)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!