| [ Return to Bugs & Features | Roadmap 1.3 | SVN ⇄ GIT ]
STR #3208
Application: | FLTK Library |
Status: | 2 - Closed w/o Resolution |
Priority: | 2 - Low, e.g. a documentation error or undocumented side-effect |
Scope: | 2 - Specific to an operating system |
Subsystem: | X11 |
Summary: | Memory leaks with fl_draw(int angle, ...) ? |
Version: | 1.3.3 |
Created By: | kdiman |
Assigned To: | manolo |
Fix Version: | Will Not Fix |
Update Notification: | |
Trouble Report Files:
Trouble Report Comments:
|
#1 | kdiman 13:31 Mar 14, 2015 |
| Hi guys!
I have found memory leaks with fl_draw(int angle, ...)
for reproduce bug: launch test/rotated_text, and change angle value: than more you will do it, you will get more the leaks ... (for each size of a font you can get ~15Mb leaks)
I spent few hours for research my code before to know that =\
PS: tested for fltk-1.3.x-r10521 (perhaps you have fixed it already, I don't know)
PSS: perhaps that is caching something ... but that its very much..
-- the best regards | |
|
#2 | AlbrechtS 14:13 Mar 14, 2015 |
| Hi Dmitrij, thanks for the report. I set priority back to "High", because this is not critical, but maybe we can change this again, dependent on the test results.
Font issues are very likely OS dependent. On which OS did you find and/or test the issue?
How did you measure the leak(s)? It would be helpful to know for testing. ... Okay, I tested under Linux (Ubuntu) with Xft enabled.
I can confirm the issue. My test instructions:
I used the command line
$ top -b | grep rotated
and could see the virtual memory of the program (rotated_text, as described by Dmitrij) increasing for about every 2nd angle selected. I used the keyboard to move the slider by 1 and waited until the next line of the 'top' output was displayed. This way I could log exact values. There may be better ways to monitor a process.
Once you are through with all angles in one font size (moving the slider left and right w/o memory increasing further), select another font size and see memory increase again.
My measurement showed the value of virtual memory increase by ~224 KiB for every 2nd selected angle and for each font size. Lots of memory.
I assume that fonts are indeed chached for a good reason, but maybe there should be a limit. Somehow.
Ideas, anybody? What happens on Windows and OS X? | |
|
#3 | greg.ercolano 17:09 Mar 21, 2015 |
| I'm finding that once I've moved through a bunch of positions, if I revisit those same angle positions, it doesn't "leak" anymore.
Also, redrawing doesn't seem to leak (i.e. rotate the text, then watch memory as you resize the window; memory size doesn't change while text is redrawn)
It seems to create a cache for every angle you draw at, and keeps it around in case you switch angles then switch back.
I /think/ in practical use, you'd only be printing at the same angle (e.g. flwm which draws window titlebars at 90 degrees), so it wouldn't grow unless you draw at new rotation angles each time.
I imagine we should at least add a warning in the docs about this, and if the cache can somehow be optional, provide a flag.
I'll check windows and osx.. | |
|
#4 | greg.ercolano 17:19 Mar 21, 2015 |
| Similar behavior on mac.
But then, when I resize the window, it grows in leaps and bounds. I think OSX must keep a cache of a screeshot of the app, because when I revisit sizes it doesn't grow.
Resizing is much more significant memory use than the font angle changes.
So apparently caching is a normal thing for both fonts and screen size changes on the mac.. | |
|
#5 | greg.ercolano 17:30 Mar 21, 2015 |
| FWIW, on the mac, all GUIs seem to grow memory use during resizing to larger screen sizes.
For instance, during resizing to a larger size, test/editor grew from RSS=7980 -> 10516 (change of 2536). But it did not change further as I resized back to smaller sizes. And if I sized up again, it only started growing in memory use when I resized up larger than I had before.
test/rotated_text was similar: during resizing, RSS=7640 -> 10556 (change of 2916) during rotated text, RSS=10556 -> 10704 (change of 148)
BTW, to check the sizes, I ran this loop in a shell to watch VSZ/RSS
while [ 1 ]; do ps aux | egrep 'PID|rotated_text' | grep -v grep; sleep 2; done
Windows.. do I really need to turn on my windows machine today.. :( | |
|
#6 | manolo 03:00 Mar 22, 2015 |
| The attached rotated.patch may allow to release the memory used by a rotated font (X11+Xft only). Its usage is exemplified with the rotated_text demo program.
It requires a small change in the FLTK source, and uses a utility function
void delete_rotated_font(Fl_Font num, int angle, int size)
that deletes a previously constructed rotated font with given angle and size.
Caution: the rotated font must have been used (text effectively drawn with it) before being deleted.
I have checked the new code runs and effectively calls XftFontClose() on the rotated Xft font, but have not checked what memory effect it has. | |
|
#7 | manolo 00:11 Apr 07, 2015 |
| I would argue this is not a real memory leak, but a normal consequence of the way rotated text is implemented under X11, through Xft: a new Xft font structure is created for each angle value and each font size. When a string is drawn using a previously used angle value, no new font is created.
This utility function allows to inform the Xft system that a font of given angle and size is no longer needed:
#include "config.h" #if defined(USE_X11) && defined(USE_XFT) #include <FL/x.H> #include <src/Fl_Font.H> extern "C" { void XftFontClose(Display*, void*); } #endif
void delete_rotated_font(Fl_Font num, int angle, int size) { #if defined(USE_X11) && defined(USE_XFT) Fl_Fontdesc *font = fl_fonts + num; Fl_Font_Descriptor *f = font->first, *previous = NULL; while (f) { if (f->size == size && f->angle == angle) break; previous = f; f = f->next; } if (!f) return; if (!previous) { font->first = f->next; } else { previous->next = f->next; } delete f; XftFontClose(fl_display, f->font); #endif }
A program can use it if it wants to control memory used by rotated fonts.
Unless other opinions arrive, I believe this STR could be closed. | |
|
#8 | AlbrechtS 05:57 Apr 07, 2015 |
| I agree that we might close this STR w/o any changes. It is definitely a font caching issue. But...
I should add that I found a similar memory increase under Windows when I tested, but obviously I forgot to post the results here.
@Dmitrij: I wonder what your program does that this memory increase was noticeable to you. Is it only a test, or is it a real application? The reason I'm asking is:
(1) If it is a test like test/rotated_text.cxx, then we should close the STR w/o changes. I believe that it is unlikely that a "real" application uses so many different font sizes and angles that this could be a problem.
(2) If my assumption (1) is wrong and it is a "real" application that rotates fonts all the time and this is something that might hurt other users as well, we should think about it. Please explain what your app does and why you think that we should "fix" the issue, which is obviously not trivial to do.
Just thinking aloud:
One way to solve the problem in FLTK would be to store a list of font structures (font cache) with a particular size (e.g. 50, 100, 1000?) and delete the oldest (least recently used [1]) font whenever the list overflows. Manolo showed how this can be done on X11 with Xft. We'd need a way to do it under Windows as well. Don't know about OS X.
[1] This would mean that we'd have to adjust the list every time a font is used (remove entry and add to the end) or find a better way to manage the font cache (e.g. usage counter per font, delete less frequently used font on overflow). | |
|
#9 | kdiman 09:13 Apr 07, 2015 |
| Manolo, thank you very much for your exploring the problem, and for the pathches and functions!
Albrecht, I will test my app with the new Manolo's patch, and will reply to here ... | |
|
#10 | manolo 09:23 Apr 07, 2015 |
| Corrigendum:
in function delete_rotated_font() at remark #7 above, it's wise to move the "delete f;" statement just after the XftFontClose(fl_display, f->font) call. | |
[ Return to Bugs & Features ]
|
| |