All strings added to patterns are interned with FcStrStaticName(), which uses a hash table of size 31, with chaining. Strings are never uninterned. This is often fine if all strings come from a finite number of fonts or config files but when they come from hundreds of web pages memory could become unconstrained. Fortunately there are a finite number of font family names and few malicious web pages trying to throw garbage names. This may become more of an issue with application fonts that are likely to each have a unique filename. "fc-match -s sans" caused 286 strings to be interned on my system. In a browsing session with Mozilla, ~300 strings were interned on startup, and after viewing ~400 web pages, the total rose only to 530. It looks like OBJECT_HASH_SIZE (31) was designed to intern fewer strings, so if string numbers get large performance may suffer. Also, FcStrHashed() should compare pointers rather than contents of strings when deciding whether they should be freed. I guess this is not currently an issue as all strings are hashed.
(In reply to comment #0) > Strings are never uninterned. Well, they are uninterned at FcFini, but I assume the application would only be expected to call FcFini on exit.
Have any suggested patch? To enlarge the hash table at least or something? Otherwise I'd like to close this until it actually becomes a problem. May be worth a comment in the source file.
(In reply to comment #0) > Also, FcStrHashed() should compare pointers rather than contents of strings > when deciding whether they should be freed. This was fixed in bug 17661, thanks.
Created attachment 33707 [details] [review] Replace static strings with reference counted strings With this, the number of strings in the hash table is limited to the number that are currently in use.
Created attachment 33708 [details] [review] Increase the number of buckets in the shared string hash table This is a reasonably conservative increase in the number of buckets in the hash table to 251. After FcInit(), there are 240 shared strings in use on my system (from configuration files I assume). The hash value is stored in each link in the chains so comparison are actually not very expensive. This change should reduce the average length of chains by a factor of 8. With the reference counted strings, it should keep the average length of chains to about 2. The number of buckets is prime so as not to rely too much on the quality of the hash function.
With the patch in comment #4 applied I get (given the random amount of fonts I've got installed) a 145k reduction in LibreOffice memory footprint (idling with a single blank writer document opened)
Both patches look good. If Firefox and OO.o run happily on it, it should be good ;).
Merged patches in master branch. thanks!
Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.