FFmpeg 6.1音频波形提取程序内存占用异常问题咨询
FFmpeg音频波形程序内存占用异常分析
问题描述
使用FFmpeg 6.1开发音频波形数据获取程序,功能正常但存在内存占用疑问:
- 程序启动时内存占用约6MB;
- 调用
get_audio_waveform函数并执行资源清理后,内存占用升至约9MB,未回落至初始的6MB(已确认释放了解码时的AVPacket和AVFrame); - 按内存泄漏的预期,若每次泄漏3MB,调用5次后内存应从6MB升至21MB,但实际调用5次后内存仅为10-11MB,怀疑是运行时库(如libc)为自身需求分配内存,咨询该现象是否正常。
相关代码
主函数
int main(int argc, char *argv[]) { // breakpoint here: ~= 6MB get_audio_waveform(); // breakpoint here: ~= 9MB }
使用的FFmpeg全局结构体
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;
清理函数
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; } }
解答
这个现象大概率是正常的,核心原因如下:
1. 运行时库的内存池缓存机制
libc等运行时库会维护内存池,当调用free或FFmpeg的av_freep释放内存时,这些内存不会立刻归还给操作系统,而是被缓存起来,用于后续的内存分配请求——这样能减少系统调用开销,提升程序性能。
- 第一次调用函数时,程序需要新内存,运行时库会向操作系统申请足够的内存(可能比实际需求多),所以内存占用从6MB涨到9MB;
- 后续调用时,运行时库直接复用缓存的内存,无需再向操作系统申请新内存,因此内存不会持续线性增长,只会有小幅波动。
2. FFmpeg的全局初始化开销
FFmpeg在第一次调用相关函数时,会完成全局初始化工作(比如注册解码器、初始化内部数据结构等),这部分初始化分配的内存会被FFmpeg全局持有,不会在单次函数调用结束后释放,属于正常的启动开销,并非内存泄漏。
3. 确认是否真的存在内存泄漏的方法
若要彻底排除内存泄漏,可使用专业检测工具:
- Linux环境用
valgrind配合memcheck工具,能精准区分运行时库缓存内存和真正未释放的内存; - Windows环境可使用Visual Studio自带内存检测工具或
Dr. Memory。
清理函数的小优化提示
avformat_close_input会自动将p_input_fmt_ctx置为nullptr,无需手动赋值;另外需确保get_audio_waveform内所有AVPacket和AVFrame都正确调用av_packet_unref和av_frame_free释放,避免遗漏。
内容的提问来源于stack exchange,提问作者happycoding-boy
相关产品推荐
相关产品推荐

