多线程视频解码器内存泄漏问题排查求助
Hey there! Let's break down the possible causes of that persistent memory leak in your video playback system—even if you’ve paired every malloc with a free, there are some sneaky environment-specific and codec-related pitfalls that could be the culprit.
Common Leak Points to Check
Codec Library Internal Allocations
If you’re using a library like FFmpeg (super common for video decoding), double-check how you’re handling core objects:AVFrame: Always pairav_frame_alloc()withav_frame_free(), and if you useav_frame_ref()to create a reference to an existing frame, make sure to callav_frame_unref()when you’re done with the referenced frame. Skippingunrefleaves the underlying buffer allocated.AVPacket:av_packet_alloc()needsav_packet_free(), andav_packet_ref()requiresav_packet_unref()to release the packet’s data buffer.- A critical gotcha for MinGW64: If you’re linking against precompiled codec libraries, ensure they use the same memory allocator as your program. For example, if the library was built with MSVC’s
msvcrt.dllallocator and your code uses MinGW’slibmingw64.dllallocator, callingfree()on memory allocated by the library won’t properly release it—leading to silent leaks.
MinGW64-Specific Memory Quirks
- Windows + MinGW can have oddities with allocation functions: If you’re using Windows API allocators like
LocalAlloc/GlobalAlloc, make sure you’re using the matchingLocalFree/GlobalFree(not standardfree()). Mixing these will definitely cause leaks. - Thread-local storage (TLS) variables: If your decoder uses TLS to store buffers or state, ensure you clean up that memory when the thread exits. TLS memory isn’t automatically freed when a thread terminates.
- Windows + MinGW can have oddities with allocation functions: If you’re using Windows API allocators like
Error Path Oversights
Memory leaks often hide in error handling code. For example:- If
avcodec_send_packet()fails, do you still free theAVPacketyou allocated? - If
avcodec_receive_frame()returns an error mid-decode, do you callav_frame_unref()on the frame you were trying to fill? - Always trace through every possible exit point in your decoding loop to confirm no allocated objects are left hanging.
- If
Buffer/Frame Pool Leaks
If you’re using a pool to reuse frames or buffers (a common optimization for video systems), check if every object taken from the pool is returned. For example, if a frame is marked as "in use" for rendering and never gets flagged as available again, the pool will keep growing as new frames are allocated to replace missing ones.
Debugging Tools for MinGW64
Since Valgrind has limited support on Windows, try these alternatives:
- Dr. Memory: A Windows-specific memory debugger that works great with MinGW64-compiled programs. It will pinpoint exact allocation sites that weren’t freed, along with call stacks.
- Custom Memory Tracking: Wrap your allocation functions to log every
malloc/freepair. Here’s a quick snippet to get started:
Add this to your code, then periodically print#include <stdlib.h> #include <stdio.h> #include <stdbool.h> typedef struct { void* ptr; const char* file; int line; } AllocRecord; #define MAX_RECORDS 10000 AllocRecord allocRecords[MAX_RECORDS]; int recordCount = 0; void* my_malloc(size_t size, const char* file, int line) { void* ptr = malloc(size); if (ptr != NULL && recordCount < MAX_RECORDS) { allocRecords[recordCount++] = (AllocRecord){ptr, file, line}; } return ptr; } void my_free(void* ptr, const char* file, int line) { for (int i = 0; i < recordCount; i++) { if (allocRecords[i].ptr == ptr) { // Shift records to fill the gap for (int j = i; j < recordCount - 1; j++) { allocRecords[j] = allocRecords[j + 1]; } recordCount--; break; } } free(ptr); } // Override standard alloc/free #define malloc(size) my_malloc(size, __FILE__, __LINE__) #define free(ptr) my_free(ptr, __FILE__, __LINE__)allocRecordsto see which allocations aren’t being freed.
Hope these tips help you track down that leak! If you can share a stripped-down snippet of your decoder code, it’d be easier to spot specific issues.
内容的提问来源于stack exchange,提问作者Cethric

