[cairo] Cairo glyph cache heap fragmentation

Kaiser Bernhard bernhard.kaiser at wipotec.com
Fri Sep 19 07:20:37 PDT 2014


Hi,

I should clarify what happens: (still cairo 1.10.0):
Callstack:
cairo_glyph_extents()
_cairo_gstate_glyph_extents()
cairo_scaled_font_glyph_extents()
_cairo_scaled_glyph_lookup()
_cairo_hash_table_lookup()
{...
if (scaled_glyph == NULL) {
        status = _cairo_scaled_font_allocate_glyph (scaled_font, &scaled_glyph);
        ..}
        }

        inside of _cairo_scaled_font_allocate_glyph
        { ...
        page = malloc (sizeof (cairo_scaled_glyph_page_t));
        ...
        status = _cairo_cache_insert (&cairo_scaled_glyph_page_cache,
                                  &page->cache_entry);
        }
You see the 'malloc (sizeof (cairo_scaled_glyph_page_t))' to insert an entry to the glyph cache?

What happens?
First you must know: realtime operating system, one global heap.
First open a surface1 (allocate the memory of a window), then write one glyph. The small piece of memory (sizeof (cairo_scaled_glyph_page_t) is allocated. So in the heap a big memory block is allocated (surface1) and above the small cache entry. Now free the surface1 (close the window). In the heap the surface is freed, the small piece of the cache remains. Now create a new surface2 > surface 1. The heapmanager gives you memory above the small piece allocated from the cache, because of surface2 > surface1. Draw again another glyph....
We have lot of windows, which are opened and closed during operating the machine. All have glyphs. But always if you close a window it may be that a small piece of memory remains and parts the heap. Because the windows have different sizes, the heap fragmentation caused by the glyph cache becomes a problem. There is still a huge amount of memory available, but it is parted by the small pieces allocated by the glyph cache. If there would be an allocator function for the glyph cache I could allocate the maximum memory needed by the cache at the startup of the system and manage the memory allocation of the cache by myself.
Additionally reducing MAX_GLYPH_PAGES_CACHED from 255 to 8 causes sometimes an assertion inside cairo.

Regards
Bernhard

_____________________________________________________________________

Bernhard Kaiser
Research & Development

Wipotec GmbH
Adam-Hoffmann-Str. 26
67657 Kaiserslautern

T +49.631.34146-0
F +49.631.34146-8640
http://www.wipotec.com


_____________________________________________________________________

Weigh Cells | Weighing systems

See our solutions. Visit us at our events
http://www.wipotec.com/german/Veranstaltungen/Unternehmen/Events

_____________________________________________________________________

Legal information:
Wipotec Wiege- und Positioniersysteme GmbH
HRB 2317 Kaiserslautern, Management: T. D�ppre, U. Wagner

This e-mail may contain confidential and/or privileged information.
If you are not the intended recipient (or have received this e-mail in error)
please notify the sender immediately and delete this e-mail. Any unauthorized
copying, disclosure or distribution of the material in this e-mail is strictly
forbidden.

-----Original Message-----
From: Behdad Esfahbod [mailto:behdad.esfahbod at gmail.com] On Behalf Of Behdad Esfahbod
Sent: Thursday, September 18, 2014 3:34 PM
To: Bryce Harrington; Kaiser Bernhard
Cc: cairo at cairographics.org
Subject: Re: [cairo] Cairo glyph cache heap fragmentation

On 14-09-17 11:32 PM, Bryce Harrington wrote:
> On Mon, Sep 15, 2014 at 02:30:07PM +0000, Kaiser Bernhard wrote:
>> Hi,
>> We use revision 1.10.0.
>> We use cairo in order to draw windows in a realtime operating system.
>> During operation windows including text are opened and closed.
>> Looking at the heap I can see, that the largest free block decreases
>> until the heap manager requests memory from the memory manager. After
>> a time the memory in the memory manager is 0 and with the next
>> request of a big memory block (opening a new window, allocating the
>> memory for the surface) we are running out of memory. The total
>> available memory does nearly not decrease in this process, we can get
>> memory in small blocks, but there is no big block available. We tried
>> to find out what happens. We logged all heap operations and found
>> out, that cairo allocates memory to add glyphs to the glyph cache.
>> The glyph cache belongs to the font, not to the window, so if the
>> window is closed (and the memory is freed), this small piece of
>> memory stays allocated 'in the middle of the heap'. We reduced the
>> define MAX_GLYPH_PAGES_CACHED from 255 to 4, and i
 t took mu

>  ch longer to run out of memory.
>> Can we disable the glyph cache or are there other solutions (update to 1.12.xx?)? Is there a possibility to use static allocated memory for glyph cache?
>
> Behdad would be a better person to answer this than me, so hopefully
> he can chime in.

Not really.  Sounds to me like a system allocator issue.  Doesn't look like there's a leak per se.

> By chance is your application multithreaded?
>
> Certainly it would be helpful to us if you could at least run a test
> against 1.12.14 (or the 1.12.16 snapshot) so we'd know if the issue is
> still in the current codebase; if it isn't there might be a patch you
> could backport if you want to stay on 1.10.0.
>
> Otherwise, my next question would be if there's a bug in
> cairo-scaled-font.c that is causing a destructor to get skipped under
> some circumstance.  cairo_scaled_font_destroy() appears to be an entry
> point, so you could put in printf's there to make sure it's actually
> getting called.  Put a printf in the constructor as well, and see if
> the construction/destruction calls are balanced.  Alternatively, you
> could run it with a memory leak checking tool like smatch, which
> should provide some beter insights.

--
behdad
http://behdad.org/



More information about the cairo mailing list