After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 158962 - Reduce memory usage of load_themes
Reduce memory usage of load_themes
Status: RESOLVED DUPLICATE of bug 154034
Product: gtk+
Classification: Platform
Component: .General
2.4.x
Other Linux
: Normal normal
: ---
Assigned To: gtk-bugs
gtk-bugs
Depends on:
Blocks:
 
 
Reported: 2004-11-21 18:51 UTC by Ben Maurer
Modified: 2004-12-22 21:47 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Ben Maurer 2004-11-21 18:51:49 UTC
Today, load_themes in gtkiconthreme.c allocates alot of memory per instance.
Here is some of the dumps I got from valgrind:

==26850== 93996 bytes in 3894 blocks are still reachable in loss record 7474 of 7480
==26850==    at 0x3414A2A8: malloc (vg_replace_malloc.c:131)
==26850==    by 0x70E526: g_malloc (in /usr/lib/libglib-2.0.so.0.400.0)
==26850==    by 0x71D208: g_strdup (in /usr/lib/libglib-2.0.so.0.400.0)
==26850==    by 0xAA5D8A: (within /usr/lib/libgtk-x11-2.0.so.0.400.0)
==26850==    by 0xAA6042: (within /usr/lib/libgtk-x11-2.0.so.0.400.0)
==26850==    by 0xAA43B3: (within /usr/lib/libgtk-x11-2.0.so.0.400.0)
==26850==    by 0xAA45A1: (within /usr/lib/libgtk-x11-2.0.so.0.400.0)
==26850==    by 0xAA47F9: (within /usr/lib/libgtk-x11-2.0.so.0.400.0)
==26850==    by 0xAA4DDA: gtk_icon_theme_has_icon (in
/usr/lib/libgtk-x11-2.0.so.0.400.0)
==26850==    by 0x5CCBF58: gnome_icon_lookup (in /usr/lib/libgnomeui-2.so.0.600.0)
==26850== 
==26850== 
==26850== 93996 bytes in 3894 blocks are still reachable in loss record 7475 of 7480
==26850==    at 0x3414A2A8: malloc (vg_replace_malloc.c:131)
==26850==    by 0x70E526: g_malloc (in /usr/lib/libglib-2.0.so.0.400.0)
==26850==    by 0x71D208: g_strdup (in /usr/lib/libglib-2.0.so.0.400.0)
==26850==    by 0xAA5D8A: (within /usr/lib/libgtk-x11-2.0.so.0.400.0)
==26850==    by 0xAA6042: (within /usr/lib/libgtk-x11-2.0.so.0.400.0)
==26850==    by 0xAA43B3: (within /usr/lib/libgtk-x11-2.0.so.0.400.0)
==26850==    by 0xAA45A1: (within /usr/lib/libgtk-x11-2.0.so.0.400.0)
==26850==    by 0xAA47F9: (within /usr/lib/libgtk-x11-2.0.so.0.400.0)
==26850==    by 0xAA48BD: gtk_icon_theme_lookup_icon (in
/usr/lib/libgtk-x11-2.0.so.0.400.0)
==26850==    by 0x5CCDD80: gnome_icon_theme_lookup_icon (in
/usr/lib/libgnomeui-2.so.0.600.0)
==26850== 
==26850== 
==26850== 99328 bytes in 97 blocks are still reachable in loss record 7476 of 7480
==26850==    at 0x3414A2A8: malloc (vg_replace_malloc.c:131)
==26850==    by 0x70E526: g_malloc (in /usr/lib/libglib-2.0.so.0.400.0)
==26850==    by 0x70F6D3: g_mem_chunk_alloc (in /usr/lib/libglib-2.0.so.0.400.0)
==26850==    by 0x6FE8C9: (within /usr/lib/libglib-2.0.so.0.400.0)
==26850==    by 0x6FDEC1: g_hash_table_replace (in /usr/lib/libglib-2.0.so.0.400.0)
==26850==    by 0xAA5DCD: (within /usr/lib/libgtk-x11-2.0.so.0.400.0)
==26850==    by 0xAA6042: (within /usr/lib/libgtk-x11-2.0.so.0.400.0)
==26850==    by 0xAA43B3: (within /usr/lib/libgtk-x11-2.0.so.0.400.0)
==26850==    by 0xAA45A1: (within /usr/lib/libgtk-x11-2.0.so.0.400.0)
==26850==    by 0xAA47F9: (within /usr/lib/libgtk-x11-2.0.so.0.400.0)


==26850== 118378 bytes in 6148 blocks are still reachable in loss record 7478 of
7480
==26850==    at 0x3414A2A8: malloc (vg_replace_malloc.c:131)
==26850==    by 0x70E526: g_malloc (in /usr/lib/libglib-2.0.so.0.400.0)
==26850==    by 0x71D208: g_strdup (in /usr/lib/libglib-2.0.so.0.400.0)
==26850==    by 0xAA5D8A: (within /usr/lib/libgtk-x11-2.0.so.0.400.0)
==26850==    by 0xAA6042: (within /usr/lib/libgtk-x11-2.0.so.0.400.0)
==26850==    by 0xAA43B3: (within /usr/lib/libgtk-x11-2.0.so.0.400.0)
==26850==    by 0xAA458C: (within /usr/lib/libgtk-x11-2.0.so.0.400.0)
==26850==    by 0xAA47F9: (within /usr/lib/libgtk-x11-2.0.so.0.400.0)
==26850==    by 0xAA48BD: gtk_icon_theme_lookup_icon (in
/usr/lib/libgtk-x11-2.0.so.0.400.0)
==26850==    by 0x5CCDD80: gnome_icon_theme_lookup_icon (in
/usr/lib/libgnomeui-2.so.0.600.0)
==26850== 
==26850== 
==26850== 118378 bytes in 6148 blocks are still reachable in loss record 7479 of
7480
==26850==    at 0x3414A2A8: malloc (vg_replace_malloc.c:131)
==26850==    by 0x70E526: g_malloc (in /usr/lib/libglib-2.0.so.0.400.0)
==26850==    by 0x71D208: g_strdup (in /usr/lib/libglib-2.0.so.0.400.0)
==26850==    by 0xAA5D8A: (within /usr/lib/libgtk-x11-2.0.so.0.400.0)
==26850==    by 0xAA6042: (within /usr/lib/libgtk-x11-2.0.so.0.400.0)
==26850==    by 0xAA43B3: (within /usr/lib/libgtk-x11-2.0.so.0.400.0)
==26850==    by 0xAA458C: (within /usr/lib/libgtk-x11-2.0.so.0.400.0)
==26850==    by 0xAA47F9: (within /usr/lib/libgtk-x11-2.0.so.0.400.0)
==26850==    by 0xAA4DDA: gtk_icon_theme_has_icon (in
/usr/lib/libgtk-x11-2.0.so.0.400.0)
==26850==    by 0x5CCBF58: gnome_icon_lookup (in /usr/lib/libgnomeui-2.so.0.600.0)
==26850== 
==26850== 
==26850== 156672 bytes in 153 blocks are still reachable in loss record 7480 of 7480
==26850==    at 0x3414A2A8: malloc (vg_replace_malloc.c:131)
==26850==    by 0x70E526: g_malloc (in /usr/lib/libglib-2.0.so.0.400.0)
==26850==    by 0x70F6D3: g_mem_chunk_alloc (in /usr/lib/libglib-2.0.so.0.400.0)
==26850==    by 0x6FE8C9: (within /usr/lib/libglib-2.0.so.0.400.0)
==26850==    by 0x6FDEC1: g_hash_table_replace (in /usr/lib/libglib-2.0.so.0.400.0)
==26850==    by 0xAA5DCD: (within /usr/lib/libgtk-x11-2.0.so.0.400.0)
==26850==    by 0xAA6042: (within /usr/lib/libgtk-x11-2.0.so.0.400.0)
==26850==    by 0xAA43B3: (within /usr/lib/libgtk-x11-2.0.so.0.400.0)
==26850==    by 0xAA458C: (within /usr/lib/libgtk-x11-2.0.so.0.400.0)
==26850==    by 0xAA47F9: (within /usr/lib/libgtk-x11-2.0.so.0.400.0)


The list goes on and on. I am running on Fedora Core 2. I think part of the
problem is that RedHat creates lots of excess symlinks in their icons folder:

[benm@omega Bluecurve]$ pwd
/usr/share/icons/Bluecurve
[benm@omega Bluecurve]$ find -name \*.png | wc -l
5348

However, Gtk+ should be designed for this type of usage. I have two ideas to
reduce usage here:

(Easy)
1) Split the name that we store into file and directory components, and then
share common strings.

Right now, this string is stored for each icon:

abs_file = g_build_filename (dir, file, NULL);

So, in the bluecurve theme with 5k icons, the following string:
/usr/share/icons/Bluecurve

is duplicated for each icon. This is over 100kb!!!!

So, what should be done is for each icon to store in different strings:
* The folder name (eg, /usr/share/icons/Bluecurve/24x24/apps/) 
* the file name (gnome-terminal.png)

Both strings will likely be duplicated, so we should share the common strings here.

How much memory would this save, well today what we have uses:

[benm@omega icons]$ find Bluecurve -name "*.png" -printf "`pwd`/%p\n" | wc -c
321917

So about 321 kb for the bluecurve folder.

The new method would use

[benm@omega icons]$ find Bluecurve -name "*.png" -printf "`pwd`/%h\n" | sort |
uniq | wc -c
1501

1.5 kb for the directory

[benm@omega icons]$ find Bluecurve -name "*.png" -printf "%f\n" | sort | uniq |
wc -c
27707

27 kb for the file names. 

So that is 28.5 kb rather than 321 kb!

(Hard)
2) Create a cache which could be mmap'd and thus shared across processes

The hard way to do this would be to have some sort of binary format that
multiple processes could mmap in order to look up icon information. So
basically, someone would ahve to create this cache and put it somewhere in the
home directory. It would contain a read-only hashtable which could be used to
look up icon information. Every process would mmap these caches into memory and
use them to look things up.

Advantages:
- the cost of the ghashtable is shared across every process. Thats a few 100 kb
according to valgrind, so multiply that by 10 or 20 apps that might use it,
gives you a fairly big savings
- Could be used along with the string reduction method
- Reduced startup time
Comment 1 Owen Taylor 2004-11-21 19:17:32 UTC
This has been addressed in GTK+ HEAD.


*** This bug has been marked as a duplicate of 154034 ***