Cooooding!!

Unity(C#)を使ったゲーム開発関連Tipsなど

Windowsアプリのメモリ使用量を取得する【Unity】

概要

UnityではないC#であればSystem.Environment.WorkingSetやProcess.GetCurrentProcess().WorkingSet64などを使ってアプリのメモリ使用量を取得できますが、Unityで作ったWindows Standaloneアプリでは何故か0を返します。調べても解決方法が見つかりませんでしたがC++でPluginを書いてみたら取得できたのでその方法を解説します。

メモリ関連の用語について

まず実装の説明をする前にメモリ関連の用語について簡単に説明しておきます。

用語 意味
スワップ 物理的なメモリ上のデータをストレージ(HDDやSSD)上に退避させること
ワーキングセット 物理的なメモリ上に確保されているメモリ量
プライベート ワーキングセット ワーキングセットのうちそのプロセスだけが使えるメモリ量
共有 ワーキングセット ワーキングセットのうち他のプロセスと共有しているメモリ量
コミットサイズ プライベートワーキングセット + スワップしたメモリ量

この記事ではワーキングセットとコミットサイズの取得方法を解説します。

実装

Pluginの実装

ダイナミックリンクライブラリ(DLL)の新規プロジェクトを作って以下のコードを書きます。

ヘッダー(.h)

#pragma once

extern "C"
{
	__declspec(dllexport) long GetWorkingSet();
	__declspec(dllexport) long GetCommitSize();
}

cpp

#include "pch.h"
#include "memory.h"
#include <psapi.h>

long GetWorkingSet()
{
	PROCESS_MEMORY_COUNTERS info;
	if (!GetProcessMemoryInfo(GetCurrentProcess(), &info, sizeof(info)))
	{
		return -1;
	}
	return (SIZE_T)info.WorkingSetSize;
}

long GetCommitSize()
{
	PROCESS_MEMORY_COUNTERS_EX info;
	if (!GetProcessMemoryInfo(
		GetCurrentProcess(),
		(PROCESS_MEMORY_COUNTERS*)&info,
		sizeof(info)
	))
	{
		return -1;
	}
	return (SIZE_T)info.PrivateUsage;
}

これをビルドしてできたdllをUnityで使います。環境にもよると思いますが 自分の環境ではソリューションプラットフォームを「x86」から「x64」に変更してビルドする必要がありました。

Unity側の実装

作ったdll(以下、MemorySize.dll)をPluginsフォルダ以下に置きます。あとは適当なクラスに以下のメソッドを定義すればメモリ量が取得できるようになります。

[DllImport("MemorySize")]
public extern static long GetWorkingSet();

[DllImport("MemorySize")]
public extern static long GetCommitSize();

GetWorkingSetはタスクマネージャーの「ワーキングセット(メモリ)」と同じ値になります。GetCommitSizeは「コミットサイズ」と同じ値になります。

ちなみに、WindowsのUnity Editorのプレビュー中にも取得できますがUnity Editor自体のメモリ使用量が含まれてしまいます。

環境

  • Visual Studio2019
  • Unity2019.2.9f1
  • Windows10 (64bit)