GNOME Bugzilla – Bug 661356
[gst-launch playbin2] leaks big chunks of memory
Last modified: 2012-01-12 19:35:07 UTC
When playing an 720p http stream with gst-launch using playbin2, I set a gdb's break point at the end of gst-launch.c, after gst_deinit(), say the print_alloc_trace () line. Wait until the break point triggered, and examine the memory usage of the gst-launch using "top" command. The gst-launch process still consumes about 11MB in RAM in my system. The symptom is much more obvious if buffer-size is set to large memory and buffer-duration is disable, for example: gst-launch-0.10 playbin2 uri="http://trailers.apple.com/movies/paramount/captainamerica/captainamerica-tlr1_a720p.m4v" buffer-size=23886080 buffer-duration=0 For the above setting, gst-launch would leak about 60MB in my system. Though this not a critical issue with gst-launch since the memory is released anyway after it exits, but would be critical for services that using playbin2 and never exits in embedded systems.
I stated wrong the "print_alloc_trace ()" above, should be gst_alloc_trace_print_live () when "trace" is enabled instead.
Could you share with us what versions of things (gstreamer, plugins) you are using and what exactly is leaked according to the trace print? Can you reproduce this on the desktop? If yes, what leaks according to valgrind --leak-check? (using the gst.supp suppression file from GStreamer's common module)
Yes, I could reproduce this on my desktop. GStreamer 0.10.28. Here is the trace from gst_alloc_trace_print_live: GstObject : -1160 GstRegistry : 0x806b2a0 GstPadTemplate : 0x81ad5c0 GstPadTemplate : 0x8206298 GstPadTemplate : 0x8206250 GstPadTemplate : 0x8206208 GstPadTemplate : 0x8206178 GstPadTemplate : 0x8206130 GstPadTemplate : 0x82060e8 GstPadTemplate : 0x82060a0 GstPadTemplate : 0x8206058 GstPadTemplate : 0x8206010 GstPadTemplate : 0x81e1ef0 GstPadTemplate : 0x81e1ea8 GstPadTemplate : 0x81e1e60 GstPadTemplate : 0x81e1dd0 GstPadTemplate : 0x81e1d88 GstPadTemplate : 0x81e1cf8 GstPadTemplate : 0x81e1cb0 GstPadTemplate : 0x8206328 GstPadTemplate : 0x82062e0 GstPadTemplate : 0x81e1c68 GstPadTemplate : 0x81e1c20 GstPadTemplate : 0x81e19c8 GstPadTemplate : 0x81e1980 GstPadTemplate : 0x81e1860 GstPadTemplate : 0x81e1818 GstPadTemplate : 0x819ce90 GstPadTemplate : 0x819ce48 GstPadTemplate : 0x819ce00 GstPadTemplate : 0x819cdb8 GstPadTemplate : 0x819cd70 GstPadTemplate : 0x819cc98 GstPadTemplate : 0x819cc50 GstPadTemplate : 0x8174f18 GstPadTemplate : 0x8174ed0 GstPadTemplate : 0x8174c90 GstPadTemplate : 0x8174c48 GstPadTemplate : 0x8174c00 GstPadTemplate : 0x8174b98 GstPadTemplate : 0x8174b50 GstPadTemplate : 0x8174b08 GstPadTemplate : 0x8174ac0 GstPadTemplate : 0x8174a78 GstPadTemplate : 0x8174a30 GstPadTemplate : 0x8174910 GstPadTemplate : 0x81748c8 GstPadTemplate : 0x8174880 GstPadTemplate : 0x8174838 And here is the summary from valgrind: ==2879== LEAK SUMMARY: ==2879== definitely lost: 5,551 bytes in 1 blocks ==2879== indirectly lost: 120 bytes in 10 blocks ==2879== possibly lost: 919,169 bytes in 2,404 blocks ==2879== still reachable: 121,528 bytes in 1,299 blocks ==2879== suppressed: 160,951 bytes in 2,358 blocks ==2879== ==2879== ERROR SUMMARY: 705 errors from 705 contexts (suppressed: 1131 from 779) --2879-- --2879-- used_suppression: 1419 <g_type_class_ref leaks> --2879-- used_suppression: 3 <tls> --2879-- used_suppression: 128 <insert_a_suppression_name_here> --2879-- used_suppression: 1 nss_parse_* memleak --2879-- used_suppression: 2 <g_type_init calloc 4> --2879-- used_suppression: 27 <glib 2.21 static type data> --2879-- used_suppression: 281 glib type registry --2879-- used_suppression: 24 <insert_a_suppression_name_here> --2879-- used_suppression: 2 <bonobo init> --2879-- used_suppression: 2 <gconf init> --2879-- used_suppression: 1 <bonobo init> --2879-- used_suppression: 2 <gconf init> --2879-- used_suppression: 255 <glib 2.21 static type data> --2879-- used_suppression: 364 dl-hack3-cond-1 ==2879== ==2879== ERROR SUMMARY: 705 errors from 705 contexts (suppressed: 1131 from 779) Thanks for your support!
First of all, please test with the the latest releases, not some ancient release. Then, it's not clear those are really leaks. Maybe the registry isn't cleaned-up properly on gst_deinit(), but the registry information stays allocated during the entire life time of the application anyway. > definitely lost: 5,551 bytes in 1 blocks Now it would be interesting to know what the details for this are (but maybe they were suppressed? In which case it's likely a known bug in another library). > For the above setting, gst-launch would leak about 60MB in my system. Where does this number come from exactly?
(In reply to comment #4) > First of all, please test with the the latest releases, not some ancient > release. I understand, just because 0.10.28 is the latest in my current Ubuntu repo. > > > For the above setting, gst-launch would leak about 60MB in my system. > > Where does this number come from exactly? I get that from "top", RES column.
Hi there, As far as I know, playbin2 includes two queues, one is queueu2 and the other is multiqueue. If you set the “buffer-size” to playbin2, this configuration will affect both queue2 and multiqueue as max-size-bytes – it means the buffering limits, unit of bytes. So I think, if the network speed was enough to fast to make full-queue. The 60MB memory usage is reasonable (24MB + 24MB). And the “resident set memory size” will be grown up due to it will make dirty page. In this case, actually it’s not a memory leak but just a heavy memory usage. Anyhow, I’d like to join this thread!
Hi Davy, That's totally fine that it takes 60MB or even more for higher bit-rate contents while it's playing. But I assume that after the pipeline is released, the memory should be freed up. In my test, I set a break point at the end of the gst-launch after it calls gst_deinit and notice the gst-launch's RES memory in "top" still says about 60M for the clip I played.
I have reproduced this issue with git HEAD version (did git pull 1 hour ago) of gstreamer (also installed latest versions of plugins bad, ugly and good). Did the same as mentioned in the original post; set a break point in gst-launch AFTER gst_deinit() and then streamed a clip over http. When gst-launch hit the breakpoint top reported 47M RES memory.
Hi there, I've reproduced this with updated git HEAD too. The "issue" is there. Can I ask anything else I could provide to moving the "bug"'s status to next stage, please? Can someone tell the impact of "live objects" GstPadTemplate after gst-deinit, please? Thanks, /ha
git HEAD of all modules, or only GStreamer core? What is the issue exactly? Top is not really a suitable means of measuring memory usage or leakage. What would be more useful is a leak report made with $ G_SLICE=always-malloc valgrind --trace-children=yes --leak-check=yes --suppressions=gst.supp gst-launch-0.10 ... Also, an exact gst-launch-0.10 pipeline with a public URI would be useful, so we can double-check ourselves. > Can someone tell the impact of "live objects" GstPadTemplate after gst-deinit, > please? None. The registry and associated objects still being there after gst_deinit() is not really something to worry about.l
(In reply to comment #10) > git HEAD of all modules, or only GStreamer core?> I did pull the git HEAD of gstreamer, base, good, bad, ugly. > What is the issue exactly? Top is not really a suitable means of measuring > memory usage or leakage. > > What would be more useful is a leak report made with > > $ G_SLICE=always-malloc valgrind --trace-children=yes --leak-check=yes > --suppressions=gst.supp gst-launch-0.10 ... > > > Also, an exact gst-launch-0.10 pipeline with a public URI would be useful, so > we can double-check ourselves. > The issue I noticed is after gst-launch did gst-deinit, the RSS memory that gst-launch using reported from "top" still say the similar amount as it was playing. I also use the "free" command to check memory before playing and at the point gst-deinit called. Same result. It only be freed after gst-launch exits, while I expect it to be freed after the pipeline unreffed. The gst-launch pipeline I used is: gst-launch-0.10 playbin2 uri="http://samples.mplayerhq.hu/HDTV/Day_after_Tomorrow.ts" buffer-size=40000000 buffer-duration=0 valgind with your options only reports about 5K lost, but I guess this lost is while the clip being played, not after the pipeline freed???: ==26173== LEAK SUMMARY: ==26173== definitely lost: 5,551 bytes in 1 blocks ==26173== indirectly lost: 120 bytes in 10 blocks ==26173== possibly lost: 38,127 bytes in 282 blocks ==26173== still reachable: 95,363 bytes in 1,958 blocks ==26173== suppressed: 518,353 bytes in 4,921 blocks ==26173== Reachable blocks (those to which a pointer was found) are not shown. ==26173== To see them, rerun with: --leak-check=full --show-reachable=yes ==26173== ==26173== Use --track-origins=yes to see where uninitialised values come from ==26173== ERROR SUMMARY: 406361 errors from 117 contexts (suppressed: 570 from 212) ==26173== --26173-- --26173-- used_suppression: 6 <insert_a_suppression_name_here> --26173-- used_suppression: 2329 <g_type_class_ref leaks> --26173-- used_suppression: 77 <g_type_init leaks> --26173-- used_suppression: 914 <insert_a_suppression_name_here> --26173-- used_suppression: 3 <tls> --26173-- used_suppression: 237 <insert_a_suppression_name_here> --26173-- used_suppression: 1 nss_parse_* memleak --26173-- used_suppression: 20 <insert_a_suppression_name_here> --26173-- used_suppression: 107 <insert_a_suppression_name_here> --26173-- used_suppression: 73 <g_type_register_fundamental leaks> --26173-- used_suppression: 2 <bonobo init> --26173-- used_suppression: 2 <gconf init> --26173-- used_suppression: 1 <bonobo init> --26173-- used_suppression: 2 <gconf init> --26173-- used_suppression: 1 <glib 2.21 static type data> --26173-- used_suppression: 370 dl-hack3-cond-1 ==26173== ==26173== ERROR SUMMARY: 406361 errors from 117 contexts (suppressed: 570 from 212) > > > Can someone tell the impact of "live objects" GstPadTemplate after gst-deinit, > > please? > > None. The registry and associated objects still being there after gst_deinit() > is not really something to worry about.l Thanks, /ha
(In reply to comment #11) > ==26173== LEAK SUMMARY: > ==26173== definitely lost: 5,551 bytes in 1 blocks > ==26173== indirectly lost: 120 bytes in 10 blocks > ==26173== possibly lost: 38,127 bytes in 282 blocks > ==26173== still reachable: 95,363 bytes in 1,958 blocks > ==26173== suppressed: 518,353 bytes in 4,921 blocks > ==26173== Reachable blocks (those to which a pointer was found) are not shown. > ==26173== To see them, rerun with: --leak-check=full --show-reachable=yes > ==26173== > ==26173== Use --track-origins=yes to see where uninitialised values come from > ==26173== ERROR SUMMARY: 406361 errors from 117 contexts (suppressed: 570 from yes, the 5 K is a real leak (having the full log would be nice).
Created attachment 199411 [details] valgrind reports 5KB lost
Thanks for that. It appears that "definite" leak is in an external module (bluez-gstreamer), you would have to file it in their bug tracker: ==4646== 5,551 bytes in 1 blocks are definitely lost in loss record 5,505 of 5,519 ==4646== at 0x4024F20: malloc (vg_replace_malloc.c:236) ==4646== by 0x63E1405: sbc_init (in /usr/lib/gstreamer-0.10/libgstbluetooth.so) ==4646== by 0x63D3A21: ??? (in /usr/lib/gstreamer-0.10/libgstbluetooth.so) ==4646== by 0x410C768: gst_type_find_factory_call_function (gsttypefindfactory.c:224)
(In reply to comment #14) > Thanks for that. It appears that "definite" leak is in an external module > (bluez-gstreamer), you would have to file it in their bug tracker: Thank you so much! No idea why the pipeline needs that lib, I'll try to find that out. Anyway, the "issue" I was asking first is the amount of RSS memory that "top"/"free" reports that the gst-launch still consume after the pipeline is freed. Especially when buffer-size is big and buffer-duration is disable, then it can consume a couple of hundreds MB after the pipeline is freed, or even after gst_deinit(). Can I ask if you could reproduce it?
> The issue I noticed is after gst-launch did gst-deinit, the RSS memory that > gst-launch using reported from "top" still say the similar amount as it was > playing. I also use the "free" command to check memory before playing and at > the point gst-deinit called. Same result. > > It only be freed after gst-launch exits, while I expect it to be freed after > the pipeline unreffed. I think you shouldn't expect that the memory is given back to the system right away (i.e. that the value in top/free goes down immediately). top and free are not suitable tools to debug memory usage issues. I'm sure google will throw up lots of pages that explain how to debug such issues properly. Closing this for now. Please submit some 'hard data' to demonstrate the leak (e.g. valgrind --leak-check logs or massif logs or so), thanks!