GNOME Bugzilla – Bug 727193
playbin: memory leaks when used for gapless audio playback
Last modified: 2016-06-20 10:57:58 UTC
Created attachment 273116 [details] Playbin test using alsasink When playbin is used for gapless playback on a 32 bit platform, the heap grows continuously (monitored via monitor_playbin.sh), with the largest growth typically occurring at a song transition. The growth from song to song is typically 100+K, and over the course of a day I've seen the heap sitting at 10M. The longer it runs gapless, the larger the heap. After the pipeline is taken to NULL and playbin is unref'd, the memory is still not returned to the system. Valgrind only shows 96 bytes lost, though possibly and still reachable are larger, output attached as valgrind.txt, consisting of ~3 tracks. As stated previously, the longer it goes, the larger the heap. Massif output attached as massif.out.4975 from ~3 tracks. I have run the test code and observed this behavior under the following configurations: - Ubuntu 12.04 32-bit VM -- Glib 2.36.2/3 built from source (also required building autoconf, automake, m4). -- Gstreamer 1.1.3, 1.2.0, 1.2.3, master (except plugins-bad, which remained at 1.2 because the build failed during the docs in master). ---- Gstreamer compiled with --with-memory-alignment=malloc and 8 -- With and without orc. The issue was originally observed with orc, but my recent testing has been without in an effort to reduce variables. -- mpg123 1.15.4 -- G_SLICE set to always-malloc or unset -- G_DEBUG set to gc-friendly or unset - Ubuntu 13.1 32-bit VM -- Glib 2.38 (system pkg) -- Gstreamer 1.2.0 - Attached playbin.c modified to use GLib main loop. - Attached code on an ARM target. On 64 bit platforms (ubuntu 12.04 and 13.1), the heap does not grow, though the overall memory footprint of the process does. At the moment, I suspect this is due to libc's more frequent use of mmap, though I haven't proven that out. I do know that the heap does not grow at all on a 64-bit target. Test code, valgrind output, and massif output attached. The "songs" and "prefix" need to be filled in with whatever you are playing and any prefix to the directory, but I've tried a variety of mp3s, the behavior occurs with all of them. To stop playback, 'echo 123 > stop' in the directory the test is executed from. One modification I have found useful is to use a fakesink instead of playbin's default sink as this causes the heap to grow much faster. I have attached the modified file as playbin_fakesink.c. Valgrind and massif output attached for this configuration as valgrind_fakesink.txt and massif.out.5586.
Created attachment 273117 [details] Valgrind output #1, using alsasink
Created attachment 273119 [details] Massif output #1, using alsasink
Created attachment 273120 [details] Monitor script
Created attachment 273121 [details] Test using fakesink
Created attachment 273122 [details] Valgrind from fakesink run
Created attachment 273123 [details] Massif from fakesink run
Confirmed this behavior with wav files, though the growth is much slower.
Observations from further testing: 1. Enabling wavparse:6 logging will prevent the heap from growing when wav files are played to a fakesink. 2. Enabling baseparse:6 logging significantly reduces the heap growth when mp3 files are played to a fake sink. Significant means that in a 2 minute span, the normal growth using fake sink is about 7M. With baseparse:6, it grows 1 - 1.5M. 3. Enabling decodebin:6 logging does NOT affect the growth of the heap when mp3s are played to a fakesink. 4. In my comment at 14:44:56, I failed to mention that I was playing the wav files to a fakesink. I need to re-run this using alsasink, but the test will take some time to be conclusive.
I'm not certain whether this is related, but better safe than sorry. When running the test (fakesink or alsa) using mp3s, with GST_TRACE=mem-live, I notice the count of: GstCaps : (14) 0xb6703b38 ("application/x-id3") increases. The longer the run, the higher the number. It does not directly correlate to a song transition, but over time, as the heap grows, this count seems to as well.
Looks like the old input/decode chains are leaked when switching. I see audio decoder instance leaks and source leaks, for example.
That's what I came to suspect, but couldn't prove with any of the tools I was using, and I don't know that code very well. How did you observe this, valgrind or just code-analysis?
I think that's probably fixed by 6ab711f3f102da0fa8d4f9feabfe7f3f4e8a0d6e from january.
Nice! I'll try this using the test above and post the results. Thanks!
I assume this got fixed then? If not, please re-open, thanks!