Forums > Dev

A hard to pin down memory leak involving sysmem_newptr

August 1, 2010 | 3:54 pm

Hi,

There’s very obviously a leak happening with one of my externals, cv.jit.shift, when it’s used in a particular fashion. There is no problem if you just send matrices at regular intervals. However, in the abstraction cv.jit.touches, I need, for every frame, to send the same matrix repeatedly (a few hundred times). That’s when problems start happening.

The culprit seems to be sysmem_newptr, which surprised me because I don’t use directly. I was able to further narrow the problem to my bang method, which surprised me even more, because I’m not doing all that much in there.

It’s probably easier to understand what’s happening by having a look at this screen grab:

http://jmpelletier.com/video/sysmem_newptr-leak.mov

That the memory seems to get released at least some time when I’m just sending individual bangs would seem to indicate a possible scheduling/garbage collection issue, but as far as I can tell whatever’s happening is in the Max API, rather than my own program.

Here’s the full source of my bang method:

//Inside main()
ps_getbox = gensym("getbox");
ps_getrot = gensym("getvertices");
ps_getmass = gensym("getmass");

/*(..)*/

void max_cv_jit_shift_bang(t_max_cv_jit_shift *x)
{
long ac = 0;
t_atom *av = NULL;
void *o;

if (max_jit_mop_getoutputmode(x))
{
o=max_jit_obex_jitob_get(x);

//Output mass
jit_object_method(o,ps_getmass,&ac,&av);
//just in case…
if (ac!=1)
error("Could not get mass from Jitter object.");
else
{
outlet_float(x->massout,jit_atom_getfloat(av));
}

//Output rotated frame
ac = 0;
av = NULL;
jit_object_method(o,ps_getrot,&ac,&av);
//just in case…
if (ac!=8)
error("Could not get rotated frame from Jitter object.");
else
{
outlet_anything(x->boxout2,_jit_sym_list,ac,av);
}

//Output bounding box
ac = 0;
av = NULL;
jit_object_method(o,ps_getbox,&ac,&av);
//just in case…
if (ac!=4)
error("Could not get bounding rectangle from Jitter object.");
else
{
outlet_anything(x->boxout,_jit_sym_list,ac,av);
}
}
}

Here’s the patch I use for testing:

– Pasted Max Patch, click to expand. –

August 1, 2010 | 11:03 pm

There might be other issuses, but minimally, it looks like you need to free the memory allocated in your get* calls. Keep in mind that attribute accessors allocate memory for av, if memory is not passed in (in which case ac would be the max atom count of the memory av points to).

i.e. before setting av to null, each time:

if (av)
sysmem_freeptr(av);

And again, finally at the end, after outputting your atoms from your getbox call.


August 2, 2010 | 1:42 am

Hi Joshua, thanks for the quick reply.

That was it. I guess it wasn’t hard to pin down at all. Too much PHP lately has made my mind soft. I don’t even remember why I was setting that pointer back to NULL…

Thanks again, you saved a few precious hairs from an untimely demise.

Jean-Marc


August 2, 2010 | 4:31 am

Glad to hear. Be sure to still zero ac and av before calling subsequent getters, so they know to allocate new pointers rather than the ones just freed.


August 2, 2010 | 7:42 am

Yes, but since the number of arguments is constant, it’s probably just better to allocate once at init time and release in free. That way, malloc won’t get called a few hundred times per frame…


Viewing 5 posts - 1 through 5 (of 5 total)