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 633869 - new Gdk.Pixbuf.from_file leaks if reference stored in Gee collection or array
new Gdk.Pixbuf.from_file leaks if reference stored in Gee collection or array
Status: RESOLVED INVALID
Product: vala
Classification: Core
Component: Bindings
0.11.x
Other Linux
: Normal normal
: ---
Assigned To: Vala maintainers
Vala maintainers
Depends on:
Blocks:
 
 
Reported: 2010-11-03 01:08 UTC by Jim Nelson
Modified: 2010-11-08 19:51 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Test case for both arrays and Gee collections (1.02 KB, text/x-vala)
2010-11-03 01:09 UTC, Jim Nelson
Details
modified test case (1.44 KB, text/plain)
2010-11-06 03:46 UTC, Evan Nemerson
Details

Description Jim Nelson 2010-11-03 01:08:49 UTC
I'm seeing this with both 0.10.1 and 0.11.1.

Spotted this on Stack Overflow: http://stackoverflow.com/questions/3703112/gdk-pixbuf-memory-leak-in-vala-or-something-else

I'm attaching a reduced test case that reproduces the problem both when pixbufs loaded from disk are stored in either a Gee collection or an array.  valgrind reports the memory leaks coming from gdk_pixbuf_new.  When I run this program the memory grows to ~90MB in system monitor although the pixbufs should be freed before the program prompts for user input.
Comment 1 Jim Nelson 2010-11-03 01:09:31 UTC
Created attachment 173736 [details]
Test case for both arrays and Gee collections
Comment 2 Evan Nemerson 2010-11-06 03:46:24 UTC
Created attachment 173933 [details]
modified test case

As far as I can tell, Vala and libgee are both doing their job perfectly. The pixbuf data does get unrefed, and according to valgrind it does get freed. I've attached a modified version of the test case which will use a GWeakNotify to report to the program when each pixbuf gets destroyed. As you can see, they all do, so if there is a leak it doesn't seem to be Vala or libgee's fault.

Running this in valgrind's leak-check tool reveals 0 definitely lost blocks, although there are a few possibly lost (the largest offender was 660 blocks--nowhere near the 20000). When you use the massif tool in valgrind to profile heap usage, you'll get something like this (apologies if it wraps, but you can easily generate something similar yourself. See http://valgrind.org/docs/manual/ms-manual.html):

    MB
90.92^                                                                       :
     |                                  :#                                  ::
     |                                 @:#                                ::::
     |                              @@:@:#                              ::@:::
     |                             @@ :@:#                            ::::@:::
     |                           @@@@ :@:#                           :::::@:::
     |                         @@@@@@ :@:#                         @::::::@:::
     |                       :@@@@@@@ :@:#                       ::@::::::@:::
     |                     :::@@@@@@@ :@:#                     ::::@::::::@:::
     |                    ::::@@@@@@@ :@:#                    :::::@::::::@:::
     |                  @@::::@@@@@@@ :@:#                  :@:::::@::::::@:::
     |                @:@@::::@@@@@@@ :@:#                :::@:::::@::::::@:::
     |              @@@ @@::::@@@@@@@ :@:#              ::: :@:::::@::::::@:::
     |            @@@ @ @@::::@@@@@@@ :@:#             :: : :@:::::@::::::@:::
     |           :@@@ @ @@::::@@@@@@@ :@:#           :::: : :@:::::@::::::@:::
     |        @@@:@@@ @ @@::::@@@@@@@ :@:#         ::: :: : :@:::::@::::::@:::
     |        @@ :@@@ @ @@::::@@@@@@@ :@:#      :::::: :: : :@:::::@::::::@:::
     |     @@@@@ :@@@ @ @@::::@@@@@@@ :@:#    ::: :::: :: : :@:::::@::::::@:::
     |   @@@@ @@ :@@@ @ @@::::@@@@@@@ :@:#   :::: :::: :: : :@:::::@::::::@:::
     |  :@@@@ @@ :@@@ @ @@::::@@@@@@@ :@:# :::::: :::: :: : :@:::::@::::::@:::
   0 +----------------------------------------------------------------------->Gi
     0                                                                   13.44

Exactly what you would expect. Memory usage spikes twice, to roughly the same level, once for each time you have 10000 pixbufs sitting around.

If you call the test functions in a loop, you'll see that memory usage doesn't really grow beyond that 90 mb level, no matter how many times you call them.

As for the discrepancy between valgrind and gnome-system-monitor, this is probably because most mallocs can't always return memory to the operating system when it is freed. I'm not exactly an expert in the area, having never really hacked on a malloc implementation, by my understanding of the problem is that malloc implementations basically have two choices for getting memory from the OS to parcel out: brk or mmap. brk is a lot faster, so that is what most implementations use (including ptmalloc2, which is what glibc uses). If you take a look at the man page for brk you'll quickly see the problem: you get one block of memory, and all you can do is decide how big it is. That means that if you have one byte of data one gigabyte into that block, your program will be unable to return that entire gigabyte to the OS.

There are a couple ways to deal with this. The first is to just let the OS handle it... the unused memory will be swapped as soon as it is needed by another application, so it probably isn't going to be a big deal. The other option is to handle operations that will spike the memory usage in another process and communicate the result (D-Bus or some other IPC mechanism will work fine, but for simple stuff g_spawn_async_with_pipes will work well, and it's a lot cheaper).

I'm going to go ahead and close this as invalid, but please feel free to reopen it if you feel that is incorrect.
Comment 3 Jim Nelson 2010-11-08 19:51:36 UTC
I think your reasoning and investigation are both sound.  I'm glad this is a non-issue -- I was going crazy looking at the C code trying to find the problem.