hi again,
Miller Puckette wrote: ...
Although Krzysztof has shown me wrong about how Pd is using memory allocation...!
no no, I would not say that! At least not without careful memory profiling. I finally managed to do some testing, but not enough to make any `statements' (what I can only say is that the basic design is beautifully logical and reading Pd code is a pleasure :-)
Please treat what follows as loose remarks which might need to be trashed after closer inspection. Also appologies for somewhat technical subject -- if you do not like such talk, then trash this right away...
Krzysztof
[Now the techie part:]
Generally speaking, the main source of memory (de/re)allocation activity are `binbufs', especially the one pointed to by inbinbuf static pointer (s_inter.c) used in parsing messages received from the gui process. Most of the time this constant creating-growing- -shrinking-deleting of inbinbuf contents is not causing much harm, since allocation sequence repeatedly reuse the same location or alternate between two locations. But whenever this sequence is intertwined with object creation etc. there could be some danger of memory fragmentation (how serious it is depends on os).
I have no idea how to limit this activity. The binbuf manipulation belongs to the very foundation of Pd and touching it has to be risky. A safer approach would be to define a nonshrinking (or rarely shrinking) binbuf variant to be substituted for the most active binbufs. But then most of the routines in m_binbuf.c would need to have nonshrinking versions.
One ad hoc improvement is probably to make a histogram of binbuf sizes generated by binbuf_text() routine (after shrinking) and choose the best (probably smaller then currently used size of 16 atoms?) initial value for nalloc variable.
During testing I also found a few memory leaks. One -- the leaking of local binbuf in save routine -- could partly explain the save-close-open-crash mystery reported by Gregorio García and Greg Rippin. This leakage can be quite large, depending on currently saved patch size. It is also very easy to stop -- canvas_saveto() of g_canvas.c is lacking a closing call of
binbuf_free(b);
}There is also a very small (18 bytes) leak which happens every time any window is closed. The two binbufs: t_editor::e_connectbuf and t_editor::e_deleted should be freed in editor_free() of g_canvas.c:
Finally there is a small (40-byte) memory amount leaking every time toplevel patch is closed. It is due to not freeing memory allocated to parent `container' object in canvas_new():
t_subcanvas *y = (t_subcanvas *)pd_new(subcanvas_class);
This is small, infrequent, and probably not worth the fuss, although there could be some danger of future bugs lurking here.
To stop this leak the canvas destruction in canvas_menuclose():
should be changed to parent subcanvas destruction:
but this creates another problem -- subcanvas class is patchable, and pd_free() routine assumes that patchable objects should have a valid binbuf pointer, while this binbuf is never created for toplevel parent subcanvases. There are three options:
Hi Krzysztof,
I finally got the two easy memory leak patches into my code (three binbuf_free() calls.) The one about the "subcanvas" object will go away when I make a big change (which I'm trying to put off until after 0.34). The change is to make the "canvas" and "subcanvas" objects the same thing, which should make several things simpler.
During testing I also found a few memory leaks. One -- the leaking of local binbuf in save routine -- could partly explain the save-close-open-crash mystery reported by Gregorio García and Greg Rippin. This leakage can be quite large, depending on currently saved patch size. It is also very easy to stop -- canvas_saveto() of g_canvas.c is lacking a closing call of
}binbuf_free(b);
There is also a very small (18 bytes) leak which happens every time any window is closed. The two binbufs: t_editor::e_connectbuf and t_editor::e_deleted should be freed in editor_free() of g_canvas.c:
- binbuf_free(x->e_connectbuf);
- binbuf_free(x->e_deleted); freebytes((void *)x, sizeof(*x));
Finally there is a small (40-byte) memory amount leaking every time toplevel patch is closed. It is due to not freeing memory allocated to parent `container' object in canvas_new():
t_subcanvas *y = (t_subcanvas *)pd_new(subcanvas_class);
This is small, infrequent, and probably not worth the fuss, although there could be some danger of future bugs lurking here...