Hello,
We have a memory leak inside Camas (and it exists most propably on IMHO as well). I've tried to debug in order to find where the leak is (I used Pike 7.2). We know the leak is inside the session object, it contains all sort of variables including other objects, mapping, string and so on (people interested in the source can get it here http://cvsweb.caudiumforge.net/cgi-bin/cvsweb.cgi/camas/server/modules/camas/camas.pike?rev=1.337&content-type=text/x-cvsweb-markup&cvsroot=caudium).
I've tried to force gc() every x minutes and when the user logout but it doesn't change the problem. I also added this in the destroy function of the session:
void destroy_object(object o) { if(o && objectp(o)) destruct(o); } void destroy() { foreach(indices(this_object()), string var) { if(this_object()[var] && !intp(this_object()[var])) { int refs = _refs(this_object()[var]); if(refs > 2) write("variable %s is referenced %d times\n", var, refs); } } destroy_object(lock); destroy_object(imapclient); destroy_object(cmail); destroy_object(prefsmailobj); destroy_object(extendedabook); destroy_object(ebookmailobj); destruct(this_object()); }
Which shows me lot of variables are referenced several times and for some of then, more than 7000 times. I also noted that the variables are usually referenced by similar number of other variables, for example I have this output:
variable draftmail is referenced 1107 times variable misspelled is referenced 7067 times variable spelling is referenced 7067 times variable deletemails is referenced 7067 times variable deletemboxes is referenced 7067 times variable prefuids is referenced 7067 times variable searchstring is referenced 1107 times variable session is referenced 1107 times
I also saw the destroy or dump_me functions are referenced 8 times while they are not used by other things in the program.
So my first questions are:
. How can I have so much objects referenced ? Is it because of some sort of reference loop ? Is _refs() working good on Pike 7.2 ? . What does a reference for a function mean ? . Is it possible to know which things reference which variables ? . What is the effect of adding a destroy() inside an object ?
I also enable debug in gc.c to find the problem but the output looks quite cryptic to me. At the beginning of the destroy I have this:
Garbage collecting ... | check: 33151 references checked, counted 489 weak refs | mark: 15799 markers referenced, 0 weak references freed, | 0 things really freed, got 0 tricky weak refs
Then lot of enqueue 0x89223ec [(nil)]: back=(nil), prev=0x81d1990, next=(nil), data=0x850cd2 4, cycle=0, flags=0x01 gc_cycle_push, recurse 0x850cd24 [(nil)] marker at 0x89495ec: flags =0x6446, refs=1, weak=-1, xrefs=0, saved=0, frame=0x89223ec [back=(nil), prev=0x 81d1990, next=(nil), data=0x850cd24, cycle=0, flags=0x01] ... dequeue 0x89222b4 [0x89222cc]: back=0x89222cc, prev=0x89223ec, next=(nil), data= 0x88ade1c, cycle=0, flags=0x01 gc_cycle_pop, pop off 0x88ade1c [0x8606e0c] marker at 0x898bb2c: flags=0x040e, refs=1, weak=0, xrefs=0, saved=1, frame=0x89222b4 [back=0xfffffff f, prev=0x89223ec, next=(nil), data=0x88ade1c, cycle=0, flags=0x09] .... gc_cycle_push, no recurse 0x88ad8ac [(nil)] marker at 0x89986b4: flags =0x040e, refs=1, weak=0, xrefs=0, saved=1, frame=(nil) and finally: | cycle: 554 internal things visited, 14 cycle ids used, | 0 weak references freed, 0 things really freed, | space for 48 gc frames used | free: 26 really freed, 528 left with live references | Killing 0x850e4c4 with 25 refs .... | Killing 0x8606e0c with 25 refs | kill: 23 objects killed, 528 things really freed | destruct: 0 things really freed done (freed 554 of 14900 objects)
. Can someone explained a little the output if it worth it ? Especially I would like to know what is a weak reference ? Why some references are weaker than others ? what does object killed mean ?
I also want to know if _next() and _prev() can be of any help to me and if yes how can I use it ?
Thank you for your time.