How to get entire memory usage at runtime in game build?

I’m trying to get the amount of memory my game is using during a game build (at runtime). For example, on Windows I can look in the “task manager” and see that my game is currently using 1,600 MB (1.6 GB). I was wondering if there was a Unity API way to do this in code/scripting – or maybe a .net API way as well? Whatever might work.

Unity has a “Profiling.Profiler.GetTotalReservedSizeLong()” function what works (as well as other functions), however that only works if the Profiler is available. In a game build, the profiler is not available. So I can’t use those Profiler functions.

I’ve also tried using these code functions:

// get the current process
Process currentProcess = System.Diagnostics.Process.GetCurrentProcess();

// get the physical mem usage
long totalBytesOfMemoryUsed = currentProcess.WorkingSet64;

This code always returns “0” bytes when I tested it in the Editor…but I havn’t tested it in an actual game build yet.

My use-case is that when my game reaches a certain number of MB used in memory on the system, I want to run something in code.

A quick google search reported that as one viable option :slight_smile: So, maybe the game build would report it correctly.

You need to call process.Refresh() before you access anything like WorkingSet64. If you want to monitor the memory you have to call Refresh() every frame that you’re monitoring, otherwise it never updates the values of anything.

https://msdn.microsoft.com/en-us/library/system.diagnostics.process.refresh(v=vs.110).aspx

1 Like

Hmm. I tested this last night using this code:

if (Input.GetKeyUp(KeyCode.R))
        {
            //long numBytes = System.GC.GetTotalMemory(false);

            Process currentProcess1 = Process.GetCurrentProcess();

            currentProcess1.Refresh();

            long totalMemoryUsedByProcess1 = currentProcess1.WorkingSet64;

            UnityEngine.Debug.Log(totalMemoryUsedByProcess1);

            //Debug.Log("- Allocated memory by Unity: " + Profiler.GetTotalAllocatedMemoryLong() + "Bytes");
        }

I’m still getting 0 bytes as a result. :face_with_spiral_eyes: Am I missing something? I tested it in the editor, and in a build and it didn’t do anything.

Hmmm that is weird. Google searching I found some people saying that if you’re calling process.WorkingSet64 from a 32-bit process it can give you the wrong number. Are you sure you’re using 64-bit everything? You’d need 64-bit Windows, the 64-bit version of the Unity Editor (for it to work in the editor) and be building as x86_64 Standalone (for it to work in a build). Or you could try process.WorkingSet instead of WorkingSet64 and see if that works; if you’re using under 4GB of RAM it should work.

Yes, as far as I know I’m using 64 bit everything. 64 bit Unity Editor, 64 bit windows, and it was built for x86_64 Standalone. I see an asset on the asset store that claims to be able to show the memory, so I might try that. If not, I’ll keep asking until I find an answer to this :slight_smile:

It says the “process.WorkingSet” command is obsolete. I think I can still use it, but visual studio is telling me it’s obsolete.

Ah, well, I can’t think of anything else that might help, unfortunately. :frowning: Good luck! Let us know if you figure out what the issue was!

No problem. Thanks for the suggestions.

We are having the same issue. We want to find out the total memory used by the process at runtime, for logging purposes.

These all return 0, even if you call proc.Refresh() first:

MonoBehaviour.print(proc.PrivateMemorySize64);
MonoBehaviour.print(proc.PeakVirtualMemorySize64);
MonoBehaviour.print(proc.PeakPagedMemorySize);
MonoBehaviour.print(proc.PagedSystemMemorySize64);
MonoBehaviour.print(proc.PagedMemorySize64);
MonoBehaviour.print(proc.NonpagedSystemMemorySize64);
MonoBehaviour.print(proc.WorkingSet64);

The PerformanceCounter you sometimes see suggested also doesn’t work:

System.Diagnostics.Process proc = System.Diagnostics.Process.GetCurrentProcess();
proc.Refresh();
PerformanceCounter pc = new PerformanceCounter();
pc.CategoryName = "Process";
pc.CounterName = "Working Set - Private";
pc.InstanceName = proc.ProcessName;
MonoBehaviour.print("process name: " + proc.ProcessName);
int processMemory = System.Convert.ToInt32(pc.NextValue()) / (int)(1024 * 1024);
MonoBehaviour.print("proc1: " + processMemory);
pc.Close();
pc.Dispose();
proc.Dispose();

Unity docs want me to use the MemoryProfiler, which is nice, but can’t be used at runtime in a built game on a player’s PC.

Sorry for reviving this old thread, but this is the only thread I found and it does seem like it’s exactly the same issue.

If the docs say so, maybe read a little bit further :wink:
Because the Memory Profiler Module’s manual page list the counters shown in the module and the names with which you can get these via ProfilerRecorders and which of these are available in release builds.

In particular, I think you might be looking for “System Used Memory”, which is getting the app memory usage directly from OS counters.

2 Likes

Oh perfect, I didn’t see these!
Thanks Martin!

1 Like