Access your Unity Memory Metrics without attaching the Profiler? I'm sold! Let me introduce you to the new Unity Memory Profiler Module available since Unity 2020.2b.
Unity-Memory-Profiler-Module-Thumbnail
Table of Contents
Imagine This
The Solution: The Unity ProfilerRecorder API
Unity Memory Profiler Module: The Metrics
Some Ideas to Try Out
What's Next?
Imagine This
Would you like to...
Run automated performance tests.
Issue a warning when your memory usage exceeds a certain amount, e.g. 500 MB.
Display your memory usage trend over the development cycle — divided by asset type
... but you never tried because you knew you couldn't because you depend on attaching the profiler?
Well, that no more.
Since Unity 2020.2 you have access to a new API that will give you all sort of metrics without even attaching the profiler.
And even better, many of these metrics work on release builds.
Juicy.
decoration-meme-mind-blown
The Solution: The Unity ProfilerRecorder API
Here's how it works.
In a script of your choice, import the Unity.Profiling namespace.
This namespace will give you access to the ProfilerRecorder class.
ProfilerRecorder will record the specific metric of your choice, e.g. texture memory used.
You start a recording session, you poll for its values and you dispose it when you're done.
A typical pattern is to use this in a memory-intensive section of your game that you want to track, such as a boss fight where many enemies are present.
Here's an example:
public class MemoryProfiler : MonoBehaviour { string _statsText; ProfilerRecorder _totalReservedMemoryRecorder; ProfilerRecorder _gcReservedMemoryRecorder; ProfilerRecorder _textureMemoryRecorder; ProfilerRecorder _meshMemoryRecorder; void OnEnable() { _totalReservedMemoryRecorder = ProfilerRecorder.StartNew(ProfilerCategory.Memory, "Total Reserved Memory"); _gcReservedMemoryRecorder = ProfilerRecorder.StartNew(ProfilerCategory.Memory, "GC Reserved Memory"); _textureMemoryRecorder = ProfilerRecorder.StartNew(ProfilerCategory.Memory, "Texture Memory"); _meshMemoryRecorder = ProfilerRecorder.StartNew(ProfilerCategory.Memory, "Mesh Memory"); } void OnDisable() { _totalReservedMemoryRecorder.Dispose(); _gcReservedMemoryRecorder.Dispose(); _textureMemoryRecorder.Dispose(); _meshMemoryRecorder.Dispose(); } void Update() { var sb = new StringBuilder(500); if (_totalReservedMemoryRecorder.Valid) sb.AppendLine($"Total Reserved Memory: {_totalReservedMemoryRecorder.LastValue}"); if (_gcReservedMemoryRecorder.Valid) sb.AppendLine($"GC Reserved Memory: {_gcReservedMemoryRecorder.LastValue}"); if (_textureMemoryRecorder.Valid) sb.AppendLine($"Texture Used Memory: {_textureMemoryRecorder.LastValue}"); if (_meshMemoryRecorder.Valid) sb.AppendLine($"Mesh Used Memory: {_meshMemoryRecorder.LastValue}"); _statsText = sb.ToString(); } void OnGUI() { GUI.TextArea(new Rect(10, 30, 250, 70), _statsText); } }
And here's how it looks:
meme-angryface
Unity Memory Profiler Module Example
Unity Memory Profiler Module: The Metrics
Right now, you have access to the following metrics
Available on Development & Release builds:
Total Used Memory |
---|
GC Used Memory |
Gfx Used Memory |
Audio Used Memory |
Video Used Memory |
Profiler Used Memory |
Available only on Development builds:
Texture Count |
---|
Mesh Count |
Material Count |
AnimationClip Count |
Asset Count |
Total Objects in Scenes |
GC Allocated In Frame |
You can see the full documentation here.
Some Ideas to Try Out
I already gave you a few, but here are a few more:
Make a special build to track the memory usage over the entire game-play during your play tests. Find the maximum and see if that's acceptable compared to your minimum requirements.
Check that the memory usage in the start menu remains the same after entering a level and coming back to the start menu. This helps locating potential memory leaks.
Record which levels take more memory and prioritize these for further optimization.