How To Mitigate Garbage Collection Errors in Custom Audio Code

Article written by Anna L.

One of the most common bugs in custom C++ audio code involves UObjects being unexpectedly deleted by Unreal’s garbage collection system. Because Unreal’s audio engine involves multiple threads, you may need to take a few more steps to ensure that audio assets are not at risk of being picked up by garbage collection when a reference to them still exists in the Audio Render Thread. This might be the problem you’re experiencing if:

- You've written C++ code that interacts with Unreal's Native Audio Engine, and/or are creating audio UAssets such as USoundBase's within C++ code
- You are getting somewhat unpredictable crashes during level teardown/transitions, or when attempting to read or write from certain audio assets
- You are failing ensures or otherwise getting errors involving audio data not existing when you attempt to read/write to it.

In order to mitigate garbage collection errors, it’s important to keep UObjects out of the Audio Render Thread. This means that it is never safe to put a UObject or a smart pointer to a UObject in a parameter to a RunCommandOnAudioThread call. Instead, its recommended to use a proxy for your UObject - e.g., a C++ object that does not inherit from UObject, but that contains the same data. The relationship between USoundWave and FWaveInstance can provide a good code example of what utilizing a proxy might look like.

It is, however, safe to reference UObjects on the Game and Audio threads, as long as the garbage collection system knows you are holding references to them. The easiest ways to do this are by making a reference to your object a UProperty, utilizing TStrongPtr, or by having a separate class inherit from a FGCObject and utilizing the AddReferencedObjects() methods.