VB6应用中WaveInRecorder.cls引发内存泄漏问题排查求助
Let's break down the likely reasons for your memory leak, especially since you've narrowed it down to the StartRecord call and suspect InitWaveInWnd:
Common Leak Points in WaveInRecorder Implementations
1. Unreleased WaveIn API Resources
The WaveInRecorder class wraps Windows' WaveIn multimedia APIs. If InitWaveInWnd calls functions like waveInOpen or waveInPrepareHeader, but your StopRecord method skips critical cleanup steps:
- You must call
waveInUnprepareHeaderfor every buffer that was prepared withwaveInPrepareHeader—failing to do this leaks buffer memory permanently. waveInClosemust only be called after all pending buffer callbacks finish. Calling it too early (while the device is still processing data) leaves system resources hanging.- VB6 doesn’t auto-clean up API-allocated resources, so every explicit API allocation needs a matching deallocation.
2. Unfreed Dynamic Memory/Buffers
If InitWaveInWnd allocates buffers (like Byte arrays or GlobalAlloc/LocalAlloc blocks) as module-level class variables, and StopRecord doesn’t properly release them:
- For VB6 dynamic arrays: Use
Eraseto clear the array, or set it toNothingto free its memory. - For API-allocated memory: Call
GlobalFree/LocalFreeto release blocks created withGlobalAlloc/LocalAlloc. - Each
StartRecordcreating a new buffer without freeing the old one will let those unused buffers accumulate in memory.
3. Leaking Window Handles
WaveIn relies on window messages for callback notifications, so InitWaveInWnd likely creates a hidden window to handle these messages. If StopRecord doesn’t destroy this window properly:
- Ensure you call
DestroyWindowon the window handle created inInitWaveInWnd, then set the handle variable to 0. - If the window isn’t destroyed, every
StartRecordwill create a new window handle—and old ones will linger. Check Task Manager’s "Handles" count for your process to confirm this.
4. Uncleaned Object References
Even if you set clsRecorder = Nothing, internal references within the WaveInRecorder class might block garbage collection:
- Check for private module-level objects (like buffer managers or callback helpers) in the class that aren’t set to
NothinginStopRecord. - If the class uses callback functions that reference VB6 objects, clear those references when stopping—lingering object references keep memory from being reclaimed.
5. VB6 String/Variant Leaks (API Interaction)
Improper handling when passing VB6 strings to WaveIn APIs (e.g., for device names or parameters) can cause leaks:
- If you used
StrPtrto pass string pointers to APIs, make sure any API-allocated string buffers are freed (e.g., withlstrfreewhere applicable). - Variants holding references to strings or objects can also retain memory if not explicitly cleared.
6. Pending Async Callbacks
WaveIn operates asynchronously. If StopRecord doesn’t wait for all pending buffer callbacks to complete before cleaning up:
- Buffers might still be in use when you call
waveInClose, leading to leaked resources. - Add logic to track buffer counts and wait for a "all buffers processed" signal before closing the device.
Troubleshooting Steps
- Inspect the
WaveInRecordersource: Look closely atInitWaveInWndandStopRecordimplementations. Verify every API allocation has a matching deallocation, and window handles/buffers are properly cleaned up. - Use VB6 profiling tools: The built-in VB6 Profiler or third-party tools like BoundsChecker can track memory allocations and highlight exactly where leaks occur.
- Test incremental cleanup: Modify
StopRecordto clean up one resource at a time (e.g., first buffers, then window, then API handles) and test memory usage after each change to isolate the leak. - Check handle counts: In Task Manager, enable the "Handles" column for your process. If the count rises with each
StartRecord/StopRecordcycle, you’re leaking window or device handles. - Manual memory tracking: Use the
GetProcessMemoryInfoAPI to log your process’s working set size after each cycle—this will help you confirm which cleanup step reduces the leak.
内容的提问来源于stack exchange,提问作者Nico van Wijk

