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
Are all these really variables in your object? If so, do they point to functions in some global module or something like that?
. How can I have so much objects referenced ?
I've no idea. The only things I can think of that get that many references are global classes like Stdio.File and efuns like aggregate_mapping and `+.
Is it because of some sort of reference loop ?
You mean like objects that refer to each other? No, that doesn't accumulate refs transitively or something like that.
Is _refs() working good on Pike 7.2 ?
Yes, fairly well. One must just be aware that there'll be an extra ref on the stack during the call.
. What does a reference for a function mean ?
It's the same thing as a reference to the object. A function reference is really a reference to the object containing the function, with an additional offset for the function identifier.
. Is it possible to know which things reference which variables ?
There's one tool: If you compile with rtl-debug, there's a function _locate_references that walks through all things and prints the ones that reference the argument (in debug style). It's really useful, especially in 7.4 and later where it has been improved to report on the more odd sorts of references.
. What is the effect of adding a destroy() inside an object ?
Not much. It's handled a bit differently inside the gc to ensure a somewhat well defined destruct order.
I also enable debug in gc.c to find the problem but the output looks quite cryptic to me. /.../
I'm not surprised. ;) Really, that output isn't useful to hunt down leaks. _locate_references is, and if you suspect C-level leaks, the dmalloc debug mode.
If you suspect a bug inside the gc itself you can compile with rtl-debug and run with -d. That enables a whole suite of self tests inside it.
Especially I would like to know what is a weak reference ?
It's a reference that "doesn't count". It behaves like a normal reference except that the gc will ignore it when determining the structures that still are referenced.
Why some references are weaker than others ?
Not sure how to respond to this. Have you looked at the comment blurb near the top of gc.c?
what does object killed mean ?
It means that an object with a destroy function was destructed because the gc determined that it wasn't referenced anymore.
I also want to know if _next() and _prev() can be of any help to me and if yes how can I use it ?
Perhaps. You can use them to make a memory walker which allows you to see which objects have most clones etc. I suggest you take a look at server/config_interface/action/debug_info.pike in a recent Roxen release if you want to do that.
/ Martin Stjernholm, Roxen IS
Previous text:
2003-06-03 01:01: Subject: Debugging memory problems
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.
-- David Gourdelier
/ Brevbäraren