Memory leak in audio pipeline

classic Classic list List threaded Threaded
1 message Options
DC
Reply | Threaded
Open this post in threaded view
|

Memory leak in audio pipeline

DC
Hi,

I have important memory leaks when building and deallocating audio transcoding pipelines in my application: more than 200kB per pipeline after creating and destroying 50 pipelines (please find attached below the pipeline diagram). In the long run, all RAM is used and even swap memory is requested because of the application's appetite.

pipeline-diagram.png

I deallocate each pipeline as expected:

    if (gst_element_set_state(s->pipeline, GST_STATE_NULL) == GST_STATE_CHANGE_FAILURE)
    {
        LOG(LOG_INFO, "[eng%05u] Unable to set the pipeline to the NULL state", s->id);
    }
    gst_object_unref (s->pipeline); /* should free all elements and bins inside */
    g_source_remove (s->bus_id);


When running valgrind with mem-check for a single pipeline, I obtain as "definitely lost":

==00:00:01:22.953 31297== 7,754 (720 direct, 7,034 indirect) bytes in 1 blocks are definitely lost in loss record 3,266 of 3,281
==00:00:01:22.953 31297==    at 0x586EA3A: g_type_create_instance (in /usr/lib64/libgobject-2.0.so.0.4200.2)
==00:00:01:22.953 31297==    by 0x585325C: ??? (in /usr/lib64/libgobject-2.0.so.0.4200.2)
==00:00:01:22.953 31297==    by 0x58551D3: g_object_new_valist (in /usr/lib64/libgobject-2.0.so.0.4200.2)
==00:00:01:22.953 31297==    by 0x58555D0: g_object_new (in /usr/lib64/libgobject-2.0.so.0.4200.2)
==00:00:01:22.953 31297==    by 0x556FBE4: gst_element_factory_create (gstelementfactory.c:373)
==00:00:01:22.953 31297==    by 0x556FEB0: gst_element_factory_make (gstelementfactory.c:449)
==00:00:01:22.953 31297==    by 0x41378F: add_encoder.isra.38 (tcgw_gstreamer.c:2494)
...
==00:00:01:22.953 31297==
==00:00:01:22.954 31297== 7,761 (720 direct, 7,041 indirect) bytes in 1 blocks are definitely lost in loss record 3,267 of 3,281
==00:00:01:22.954 31297==    at 0x586EA3A: g_type_create_instance (in /usr/lib64/libgobject-2.0.so.0.4200.2)
==00:00:01:22.954 31297==    by 0x585325C: ??? (in /usr/lib64/libgobject-2.0.so.0.4200.2)
==00:00:01:22.954 31297==    by 0x58551D3: g_object_new_valist (in /usr/lib64/libgobject-2.0.so.0.4200.2)
==00:00:01:22.954 31297==    by 0x58555D0: g_object_new (in /usr/lib64/libgobject-2.0.so.0.4200.2)
==00:00:01:22.954 31297==    by 0x556FBE4: gst_element_factory_create (gstelementfactory.c:373)
==00:00:01:22.954 31297==    by 0x556FEB0: gst_element_factory_make (gstelementfactory.c:449)
==00:00:01:22.954 31297==    by 0x41378F: add_encoder.isra.38 (tcgw_gstreamer.c:2494)
...
==00:00:01:22.954 31297== 12,233 (712 direct, 11,521 indirect) bytes in 1 blocks are definitely lost in loss record 3,273 of 3,281
==00:00:01:22.954 31297==    at 0x586EA3A: g_type_create_instance (in /usr/lib64/libgobject-2.0.so.0.4200.2)
==00:00:01:22.954 31297==    by 0x585325C: ??? (in /usr/lib64/libgobject-2.0.so.0.4200.2)
==00:00:01:22.954 31297==    by 0x58551D3: g_object_new_valist (in /usr/lib64/libgobject-2.0.so.0.4200.2)
==00:00:01:22.954 31297==    by 0x58555D0: g_object_new (in /usr/lib64/libgobject-2.0.so.0.4200.2)
==00:00:01:22.954 31297==    by 0x556FBE4: gst_element_factory_create (gstelementfactory.c:373)
==00:00:01:22.954 31297==    by 0x556FEB0: gst_element_factory_make (gstelementfactory.c:449)
==00:00:01:22.954 31297==    by 0x418220: add_decoder (tcgw_gstreamer.c:1667)
...
==00:00:01:22.954 31297== 12,234 (720 direct, 11,514 indirect) bytes in 1 blocks are definitely lost in loss record 3,274 of 3,281
==00:00:01:22.954 31297==    at 0x586EA3A: g_type_create_instance (in /usr/lib64/libgobject-2.0.so.0.4200.2)
==00:00:01:22.954 31297==    by 0x585325C: ??? (in /usr/lib64/libgobject-2.0.so.0.4200.2)
==00:00:01:22.954 31297==    by 0x58551D3: g_object_new_valist (in /usr/lib64/libgobject-2.0.so.0.4200.2)
==00:00:01:22.954 31297==    by 0x58555D0: g_object_new (in /usr/lib64/libgobject-2.0.so.0.4200.2)
==00:00:01:22.954 31297==    by 0x556FBE4: gst_element_factory_create (gstelementfactory.c:373)
==00:00:01:22.954 31297==    by 0x556FEB0: gst_element_factory_make (gstelementfactory.c:449)
==00:00:01:22.954 31297==    by 0x418220: add_decoder (tcgw_gstreamer.c:1667)
...
==00:00:01:22.955 31297== LEAK SUMMARY:
==00:00:01:22.955 31297==    definitely lost: 2,872 bytes in 4 blocks
==00:00:01:22.955 31297==    indirectly lost: 37,110 bytes in 92 blocks
==00:00:01:22.955 31297==      possibly lost: 322 bytes in 3 blocks
==00:00:01:22.955 31297==    still reachable: 353,600 bytes in 1,116 blocks

mem-check1.txt
           
Which looks linked to the decoder/encoder elements (though only ~40kB). I tried to deference them directly before deferencing the pipeline (although they should have been dereferenced when dereferencing the pipeline):

        gst_object_unref(bin_src->decoder);
        gst_object_unref(bin_sink->encoder);

                                                                 
Mem-check now looks much better...

==00:00:00:49.823 22590== LEAK SUMMARY:
==00:00:00:49.823 22590==    definitely lost: 0 bytes in 0 blocks
==00:00:00:49.823 22590==    indirectly lost: 0 bytes in 0 blocks
==00:00:00:49.823 22590==      possibly lost: 322 bytes in 3 blocks
==00:00:00:49.823 22590==    still reachable: 353,602 bytes in 1,116 blocks
==00:00:00:49.823 22590==         suppressed: 248,844 bytes in 2,280 blocks

mem-check2.txt

...but memory leaks are still huge (~180kb) when measured with top.

Running valgrind with massif, several minutes after the last dereferenced pipeline, the detailed snapshot shows lots of allocations related to elements in the pipelines, although pipelines have already been freed long ago (see file attached), examples:

massif-1.txt

...
| | | | ->05.04% (229,384B) 0x584B25B: ??? (in /usr/lib64/libgobject-2.0.so.0.4200.2)
| | | |   ->04.93% (224,200B) 0x584CE1B: g_object_newv (in /usr/lib64/libgobject-2.0.so.0.4200.2)
| | | |   | ->04.22% (191,976B) 0x584D5E2: g_object_new (in /usr/lib64/libgobject-2.0.so.0.4200.2)
| | | |   | | ->02.38% (108,232B) 0x879F062: rtp_source_new (rtpsource.c:595)
...

| | | |   | | ->01.65% (75,072B) 0x87A61A2: gst_rtp_session_init (gstrtpsession.c:808)
| | | |   | | | ->01.65% (75,072B) 0x5866999: g_type_create_instance (in /usr/lib64/libgobject-2.0.so.0.4200.2)
| | | |   | | |   ->01.65% (75,072B) 0x584B25B: ??? (in /usr/lib64/libgobject-2.0.so.0.4200.2)
| | | |   | | |     ->01.65% (75,072B) 0x584D1D2: g_object_new_valist (in /usr/lib64/libgobject-2.0.so.0.4200.2)
| | | |   | | |       ->01.65% (75,072B) 0x584D5CF: g_object_new (in /usr/lib64/libgobject-2.0.so.0.4200.2)
| | | |   | | |         ->01.65% (75,072B) 0x5567BE3: gst_element_factory_create (gstelementfactory.c:373)
| | | |   | | |           ->01.65% (75,072B) 0x5567EAF: gst_element_factory_make (gstelementfactory.c:449)
...
| | | |   | | ->00.19% (8,672B) 0x8788F0C: gst_rtp_jitter_buffer_init (gstrtpjitterbuffer.c:984)
| | | |   | | | ->00.19% (8,672B) 0x5866999: g_type_create_instance (in /usr/lib64/libgobject-2.0.so.0.4200.2)
| | | |   | | |   ->00.19% (8,672B) 0x584B25B: ??? (in /usr/lib64/libgobject-2.0.so.0.4200.2)
| | | |   | | |     ->00.19% (8,672B) 0x584D1D2: g_object_new_valist (in /usr/lib64/libgobject-2.0.so.0.4200.2)
| | | |   | | |       ->00.19% (8,672B) 0x584D5CF: g_object_new (in /usr/lib64/libgobject-2.0.so.0.4200.2)
| | | |   | | |         ->00.19% (8,672B) 0x5567BE3: gst_element_factory_create (gstelementfactory.c:373)
...
| ->00.72% (32,768B) 0x52BA1EC: gst_adapter_init (gstadapter.c:198)
| | ->00.72% (32,768B) 0x5866999: g_type_create_instance (in /usr/lib64/libgobject-2.0.so.0.4200.2)
| |   ->00.72% (32,768B) 0x584B25B: ??? (in /usr/lib64/libgobject-2.0.so.0.4200.2)
| |     ->00.72% (32,768B) 0x584CE1B: g_object_newv (in /usr/lib64/libgobject-2.0.so.0.4200.2)
| |       ->00.18% (8,192B) 0x5077D88: gst_audio_decoder_init (gstaudiodecoder.c:473)
| |       | ->00.18% (8,192B) 0x5866956: g_type_create_instance (in /usr/lib64/libgobject-2.0.so.0.4200.2)
| |       |   ->00.18% (8,192B) 0x584B25B: ??? (in /usr/lib64/libgobject-2.0.so.0.4200.2)
| |       |     ->00.18% (8,192B) 0x584D1D2: g_object_new_valist (in /usr/lib64/libgobject-2.0.so.0.4200.2)
| |       |       ->00.18% (8,192B) 0x584D5CF: g_object_new (in /usr/lib64/libgobject-2.0.so.0.4200.2)
| |       |         ->00.18% (8,192B) 0x5567BE3: gst_element_factory_create (gstelementfactory.c:373)
| |       |           ->00.18% (8,192B) 0x5567EAF: gst_element_factory_make (gstelementfactory.c:449)
...

Even encoder/decoder-related, which have been explicitly dereferenced.

What is missing when deallocating the pipeline?

Thanks for your help.