|
From: Daniel J S. <dan...@ie...> - 2004-10-03 00:16:59
|
I discovered memory leak problems in gnuplot_x11 a few days ago and have
uncovered a couple things so far.
The first bug I have fixed with the attached patch. Please apply this
short patch to CVS immediately. The problem also exists in 4.0.0,
unfortunately, so perhaps it should be fixed there as well. It isn't a
severe leak. When a plot is deleted, the commands in the buffer are
cleared. However, the plot->commands array is also dynamic and I
overlooked freeing that when building the linked list. (So my bad.) In
the 16 window scheme previous, this was not a problem because the
pointer "plot" was not discarded. However, when removing the link from
the list, "plot" is discarded and hence a valid plot->commands array is
discarded. The memory usage grows at a noticeable rate when there are a
lot of commands in windows that are closed often, so likely not too
noticeable.
Now the second problem. I haven't solved this one yet and I may need
some help from Ethan. Here is what I am noticing in CVS and in 4.0.0 on
my machine. When I start up gnuplot and do a plot, say "plot x", and
then resize the window with the mouse or redisplay it in some way, the
memory usage climbs at an appreciable rate. However, creating another
X11 plot and resizing does not show this behavior. I eventually noticed
that there is one extra command in the plot buffer for only the very
first plot. In the case of "plot x" it is 223 commands for the first
plot, 222 thereafter; and here is how they differ:
QAAWLMVMVJQTWL...
QAAWLMVMVJTWLM...
There is an extra 'Q' or font command at the tenth spot. I did not go
any further investigating why this extra Q is there for the first plot.
Perhaps Ethan can help. Is it gnuplot that is putting in the extra
command? Is it a mouse feedback command?
In any case, the question is why is this causing memory to disappear so
quickly? Those two command strings in the first plot are "QD" and then
later "QF". It is the QF causing problems which is executed as:
switch (buffer[1]) {
case 'F':
/* Strip out just the font name */
c = &(buffer[strlen(buffer)-1]);
while (*c <= ' ') *c-- = '\0';
pr_font(&buffer[2]);
XSetFont(dpy,gc,font->fid);
break;
When I comment out the "XSetFont" function, the memory leak goes away.
So, upon redisplaying the plot, there is an XClearWindow(). Does there
also need to be something that frees the fonts in the X window? (I'm
just guessing.)
Dan
PS: There may be another potential minor leak, but I don't think it
happens by default. This bit of code:
case ' ': {
static int cmd_tried = 0;
static char *cmd = NULL;
static unsigned long newGnuplotXID = 0;
/* If the "-ctrlq" resource is set, ignore ' ' unless
control key is also pressed */
if (ctrlq && !(modifier_mask & Mod_Ctrl))
break;
if (!cmd_tried)
cmd = getMultiTabConsoleSwitchCommand(&newGnuplotXID);
/* overwrite gnuplotXID (re)set after x11.trm:X11_options() */
if (newGnuplotXID) gnuplotXID = newGnuplotXID;
if (cmd) system(cmd);
}
if (gnuplotXID) {
XMapRaised(dpy, gnuplotXID);
XSetInputFocus(dpy, gnuplotXID, 0 /*revert */ ,
CurrentTime);
XFlush(dpy);
}
return;
If successful "getMultiTab..." mallocs a command on the heap and returns
it. It is used by the above system command, but nowhere is that pointer
freed after its use. The variables are static, and "(!cmd_tried)" would
protect against getting the command a second time if only it were set to
1 after getting the command.
|