c++ffmpeg

ffmpeg memory usage, or memory leaks


I'v write a simple program to get audio waveform data, which using ffmpeg version 6.1. And program works fine. But I get a problem: when program running at begin, system report using about 6MB memory, but when I call the function and cleanup the resouce alloced, system report about 9MB memory used. In my theory, after cleanup, it should be 6MB again. [I'm sure, I freed the AVPacket when read stream, and AVFrame for decoding.] My question is: Is this normal or not?

int main(int argc, char *argv[])
{
    // breakpoint here: ~= 6MB
    get_audio_waveform();
    // breakpoint here: ~= 9MB
}

The ffmpeg struct I used:

AVFormatContext*    p_input_fmt_ctx = nullptr;
AVCodecContext*     p_input_cdc_ctx = nullptr;
SwrContext*         p_resampler_ctx = nullptr;
AVAudioFifo*        p_audio_fifo    = nullptr;
uint8_t**           p_converted_input = nullptr;
uint8_t**           p_converted_output = nullptr;

The cleanup func:

void _cleanup()
{
    avformat_close_input(&p_input_fmt_ctx);
    avcodec_free_context(&p_input_cdc_ctx);
    swr_free(&p_resampler_ctx);
    
    if (p_audio_fifo)
    {
        av_audio_fifo_reset(p_audio_fifo);
        av_audio_fifo_free(p_audio_fifo);
        p_audio_fifo = nullptr;
    }
    
    if (p_converted_input)
    {
        av_freep(&p_converted_input[0]);
        free(p_converted_input);
        p_converted_input = nullptr;
    }
    
    if (p_converted_output)
    {
        av_freep(&p_converted_output[0]);
        free(p_converted_output);
        p_converted_output = nullptr;
    }
}

In my opinion,If this function have about 3MB memory leaks[6MB -> 9MB]. when I run this function 5-times, it should be about 15MB memory leaks.[6MB -> 21MB]. But when I run this function 5-times. After that, system just reports about 10-11 memory used. I doubt wheather program uses runtime library (i.e. libc or equivalent) and the library allocates some memory for own needs? I do not known which step is wrong!:(


Solution

  • malloc usually does not release memory to the system when you call free for performance reasons.

    If you use glibc on Linux you can control it using mallopt function or by setting env variables.

    Example:

    #include <malloc.h>
    #include <stdlib.h>
    
    int main() {
        mallopt(M_TRIM_THRESHOLD, 128);   // Release even small chunks
        mallopt(M_MMAP_THRESHOLD, 1024); // Use mmap for allocations >1 KB
    
        void *ptr = malloc(10 * 1024 * 1024); // Allocate 10 MB
        free(ptr); // Freed memory is more likely to return to the system
    
        return 0;
    }
    
       M_TRIM_THRESHOLD
              When the amount of contiguous free memory at the top of
              the heap grows sufficiently large, free(3) employs sbrk(2)
              to release this memory back to the system.  (This can be
              useful in programs that continue to execute for a long
              period after freeing a significant amount of memory.)  The
              M_TRIM_THRESHOLD parameter specifies the minimum size (in
              bytes) that this block of memory must reach before sbrk(2)
              is used to trim the heap.
    
              The default value for this parameter is 128*1024.  Setting
              M_TRIM_THRESHOLD to -1 disables trimming completely.
    
              Modifying M_TRIM_THRESHOLD is a trade-off between
              increasing the number of system calls (when the parameter
              is set low) and wasting unused memory at the top of the
              heap (when the parameter is set high).
    

    In your case:

    int main(int argc, char *argv[])
    {
        mallopt(M_TRIM_THRESHOLD, 8);
        // breakpoint here: ~= 6MB
        get_audio_waveform();
        // breakpoint here: check here
    }