自作のQuest 3アプリで、ヘッドセットを外して着け直すたびに、GPUのメモリが約630MB増えていた。4回着け外しすると、起動直後に790MBだったものが4.58GBになる。
原因はUnityのOpenXR設定「Optimize Buffer Discards (Vulkan)」が無効になっていたことだと見ている。有効にしたあとは、同じ4回で160MBから171MBまでしか増えなくなった。
切り分けで効いたのは、ヘッドセットを被らずに「外した」「着けた」をPCから起こす手順だった。最初は別の操作が原因だと取り違えていたので、その経緯も含めて書く。
- ヘッドセットを外して着け直すたびに、GPUメモリが約630MB増えていた。
- adbで近接センサーの状態を送り、被らずに着け外しを再現して測った。
- OpenXRの「Optimize Buffer Discards (Vulkan)」を有効にして、増加がほぼ止まった。
外して着け直すたびに、630MB増えていた
Claude Codeで4週間作っているQuest 3アプリ
2026年9月26日から、Quest 3で動く自作アプリをClaude Codeと作っている。10月23日時点でコミットは297、コミットがあった日は19日だ。コードもコミットもほぼClaude Codeに任せていて、筆者が決めているのは作る方針と動作の良し悪し、それにQuestの実機で動きを確かめることだ。
使っている本体は、2年前に中古で買ったQuest 3だ。週1回か隔週1回しか被らなくなっていたが、開発を始めてからはほぼ毎日、動作確認で被っている。
環境はUnity 6000.6.3f1、Meta XR Core SDK 207.0.0、OpenXR 1.18.0。ビルドには8〜25分かかり、できたAPKをadbでQuestに入れて確かめる。1回の確認に時間がかかるので、実機で起きる問題ほど追うのが重い。
測ったのはdumpsysのGL mtrack
GPUのメモリは、Androidのdumpsys meminfoで見た。Questの中身はAndroidなので、PCからadbで次のように打てばアプリのメモリの内訳が出る。
adb shell dumpsys meminfo <パッケージ名>
見たのは内訳のうち「GL mtrack」の行だ。Androidの公式ドキュメントは、この行が何を表すかまでは説明していない。ここでは、グラフィックス用に確保されたメモリの目安として見ている。
2026年10月4日の記録では、ヘッドセットを外して着け直すたびに、この値が約630MB増えていた。ときには倍の約1.26GB増えることもあった。4回の着け外しで790MBから4.58GBになっている。
Androidは、メモリが足りなくなるとlmkd(low memory killer daemon)が優先度の低いプロセスから終了させる。着け外しのたびに数百MBずつ増える作りだと、使い続けるうちにアプリが落とされかねない。
最初は、別の操作のせいだと思っていた
2つのことが同時に起きていた
最初は、パススルー(周りの現実の映像を映す機能)の切り替えが原因だと見ていた。このアプリでは、パススルーの切り替えと、ヘッドセットの着け外しが同じタイミングで起きていた。増えた瞬間に起きていたことが2つあり、目立つほうを犯人にしてしまった。

同時に起きたことが2つあると、つい目立つほうを疑ってしまう。片方だけを起こして測れる手順があれば、最初から切り分けられた。
数字の読み違いで遠回りしたのは、これが初めてではない。ブログの自動リライトでも、Search Consoleの「CTR 0%」の正体が目次リンクだったことに気づくまで、別の原因を疑っていた。
被らずに「外した」「着けた」を起こす
着け外しのたびに実際に被っていると、測るたびに手間がかかるうえ、ほかの操作も混ざる。そこで、PCからadbで近接センサーの状態を送り、被らずに着け外しを起こすようにした。
# 外したことにする(約28秒待つ)
adb shell am broadcast -a com.oculus.vrpowermanager.prox_far
# 着けたことにする(約18秒待つ)
adb shell am broadcast -a com.oculus.vrpowermanager.prox_close
# 作業が終わったら必ず送る(センサーの上書きを解除する)
adb shell am broadcast -a com.oculus.vrpowermanager.automation_disable
外したことにすると、15秒ほどで画面が消え、そのあとアプリが一時停止の状態になる。着けたことにすると、アプリが再開し、装着状態が変わったという通知がアプリに届く。待ち時間は、この切り替わりが終わるのを待つためだ。
最後の1行は忘れやすい。送らないと、近接センサーの状態が上書きされたまま残る。2026年10月7日に実際にこれをやり、ヘッドセットを被っているのに約15秒でスリープするようになった。
設定1つで、増えなくなった
Optimize Buffer Discards (Vulkan) を有効にする
効いたのは、UnityのOpenXRの設定「Optimize Buffer Discards (Vulkan)」だった。ただ、Project Settingsの「XR Plug-in Management」→「OpenXR」→ Androidのタブを開いても、この項目のチェック欄は出てこなかった。

Unityの画面でこのチェック欄が出るのは、同じAndroidのタブの機能一覧で「Meta Quest Support」を有効にし、その歯車から設定を開いたときだけだ。筆者のプロジェクトではMeta Quest Supportを使っていない。そこで、設定ファイル Assets/XR/Settings/OpenXR Package Settings.asset のAndroid向けの設定にある m_optimizeBufferDiscards を 0 から 1 に書き換えた。変更はこの1行だけだ。
同じファイルの中で、Meta Quest Support側の同名の値は、書き換える前から 1 になっていた。それでも増え続けていたので、Meta Quest Supportを無効にしている構成では、そちらの値は効いていなかったと見ている。Meta Quest Supportを使っているなら、画面のチェック欄で済むはずだ。
Metaの開発者向けドキュメントによると、QuestのGPUでは、MSAA(アンチエイリアスの一種)用のバッファをメインメモリに置かずに済ませられる。この設定はその仕組みを使うもので、Quest 3の標準解像度で4x MSAAなら、片目あたり約90MB、両目で約180MBの節約になるとしている。
有効にしてから、同じ手順で測り直した。値はGPUメモリ(dumpsys meminfoのGL mtrack)で、2026年10月4日の実測だ。
| 計測した時点 | 対策前 | 対策後 |
|---|---|---|
| 起動直後 | 790MB | 160MB |
| 4回着け外し後 | 4,580MB | 171MB |
4回の着け外しで増えたのは約11MBで、1回あたりにすると2〜4MBだ。起動直後の値も790MBから160MBに下がった。
原因は「推定」のまま
このアプリの画質設定(Medium)ではMSAAが4xになっている。着け外しのたびに約630MBずつ増え、MSAA用のバッファを扱う設定を有効にしたら増えなくなった。ここから、着け直すたびにMSAA用の描画先が作り直され、古いものが解放されずに残っていたと見ている。
ただし、解放されていないことを直接確かめたログは無い。Metaのドキュメントにある節約量(両目で約180MB)と、1回あたり約630MBという増え方の大きさも、まだ結び付けて説明できていない。状況から一番筋が通る原因、というところまでだ。
有効にする前に知っておきたいこと
Metaのドキュメントは「ほぼすべてのMeta Questアプリで有効にすべき」としている。一方で、Unityには、この設定とフォービエイテッドレンダリングを両方オンにすると、描画を拡張する機能(Scriptable Renderer Feature)が崩れるという不具合報告がある。報告の対象はOpenXR 1.15.1〜1.16.0-pre.2で、状態は「Won’t Fix」で閉じられている。描画を自分で拡張しているなら、有効にしたあとに見た目が崩れていないかを実機で確かめたい。
Claude Codeに任せた部分、任せなかった部分
設定の変更も、測るためのadbの手順も、Claude Codeのセッションの中で進めた。筆者がやったのは、実機で被って動きを確かめることと、どの方向で直すかを決めることだ。
Claude Codeで個人サービスを作ったときは、バグを伝えれば原因まで特定してくれる場面が多かった。今回は事情が違った。原因はコードではなく、Unityの設定ファイルの1行だった。しかも症状は、実機でヘッドセットを着け外ししたときにしか出ない。
そういう問題で効いたのは、「被らずに再現する」「同じ値を同じ手順で測る」という土台を先に作ることだった。土台ができてしまえば、設定を変えて測り直すのは速い。
よくある質問
- QQuestアプリで、ヘッドセットを外すたびにメモリが増えるのはなぜ?
- A
筆者の自作アプリでは、着け外しのたびにGPUメモリ(dumpsys meminfoのGL mtrack)が約630MB増えていた。UnityのOpenXR設定「Optimize Buffer Discards (Vulkan)」を有効にすると、4回の着け外しで増えたのは約11MBになった。Meta Quest Supportを使っていない構成では画面にチェック欄が出ないので、設定ファイルの値を書き換えた。MSAA用のバッファが着け直しのたびに作り直されていたと見ているが、直接確かめたログは無く、推定にとどまる。
- QQuestを被らずに、着けた・外した状態を再現できる?
- A
筆者の環境(Windows 11・Quest 3)では、adbで「adb shell am broadcast -a com.oculus.vrpowermanager.prox_far」を送ると外した扱い、「prox_close」で着けた扱いになった。それぞれ約28秒・約18秒待つと切り替わりが終わる。公式ドキュメントで見つけた手順ではない。終わったら「automation_disable」を送らないと、被っていても約15秒でスリープする状態が残る。
- QOptimize Buffer Discards (Vulkan) を有効にして困ることはある?
- A
Metaの開発者向けドキュメントは、ほぼすべてのQuestアプリで有効にすべきとしている。一方、Unityの不具合報告では、フォービエイテッドレンダリングと併用するとScriptable Renderer Featureの描画が崩れる例がある(OpenXR 1.15.1〜1.16.0-pre.2、Won’t Fix)。筆者のアプリでは有効にしてGPUメモリが4回の着け外しで4.58GBから171MBに収まったが、描画を拡張している場合は実機で見た目を確かめたい。
着け外しは、被らずに再現して測る
ヘッドセットを外して着け直すだけで数百MBずつ増える問題は、設定ファイルの1行で止まった。ただ、そこに行き着けたのは、着け外しだけをPCから起こし、同じ値を同じ手順で測れるようにしてからだった。
Questのアプリで、実機でしか出ない症状を追うなら、まず被らずに再現できる手順を作る。終わったら automation_disable を送るのを忘れずに。

