Instruments でMonoメモリ割り当てを確認する方法

**今回の主な話題：**

1）InstrumentsでMonoメモリ割り当てを確認する方法

2）Addressable v1.11.2に関する疑問

3）UV2の展開によって引き起こしたMeshの頂点数の増加

4）Unityエディターでのコードのコンパイル速度の向上

5）Renderdocのデバッグに関する疑問


---
##Memory
**Q：たとえば、10MBのアレイが割り当てられると、少なくとも10MBのMonoメモリがUnity Profilerで開かれます。**

**では、Instrumentsで、割り当てられたメモリ情報をどのように確認しますか？Allocationsの情報は、このプロセスで割り当てられたすべてのメモリ情報ですか？100MBのメモリを割り当てようとしましたが、Allocationsの統計は増加しませんでした。**
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/3977fe96-52fd-12eb-8384-1e53db3538dc.png)
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/fa0e7ca8-2cec-b07b-647e-253f2e5c2b37.png)
>
A：こちらでもテストしました：
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/df929d57-6fa2-c7e7-0a42-cd14034311b3.png)
100MBのintアレイを作成しました。実際のSizeは400MBであるはずです。
次に、Profileに移動して次のことを確認します。
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/c38b40b0-e6f4-7e03-0bd7-cc8e728a7d59.png)
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/5b5d16f9-4d92-3585-02fa-0fe376395fcb.png)
ManagedHeapが400MBのスペースを正しく割り当てていることがわかります。
それに、iOSをパッケージ化し、Xcodeで実行します。実行する前に、まず、RunというSchemeのMallocStackを選択します。
![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/ebccf1b7-64fa-9d4f-53b1-4b294fa663a9.png)
RUNした後、「Memory」をクリックし、メモリグラフMemory Graphをエクスポートして次のことを確認します。
![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/9906dd53-899c-9e9e-704a-cb4765d4aa7c.png)
アプリのメモリはVirtualMemoryスペースに割り当てられているため、VM RegionsのVM_ALLOCATE部分を確認してください。
![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/c7bdae4a-1fd9-4adb-8413-98a5c5a4701c.png)
128X3 +16というちょうど400MBの割り当てはであることがわかります。
コールスタックも非常に簡単に判別できます。
![9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/5ba3585d-b129-bb0f-b497-83f9fc7b12b3.png)
これがテストコードです。
次に、Instrumentsについて見ていきます。まずはAllocationsの部分です。下にはいくつかのオプションがあることに注意してくだいさい。
![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/38a711c0-ab85-578f-b6ea-0a75c106809f.png)
最後のオプションに注意してください。一番目のオプションを選択する場合は、
All Heap＆Anonymous VM、All HeapはAppの実際に割り当てられた物理スペースに対応します。VMが含まれません。それに対し、Anonymous VMの公式な説明は次のとおりです：
interesting VM regions such as graphics- and Core Data-related. Hides mapped files, dylibs, and some large reserved VM regions。
したがって、比較的大きな予約済み割り当てスペースは表示されません。
このオプションを「All VM Regions」に切り替えると、割り当てられた400Mが表示されます。
![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/e1a45689-157b-4337-0784-a7cb9f4b1533.png)
また、右側の詳細ページには、コールスタックも正しく表示されます。
![12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/b2642468-a04e-77ad-4480-972b807e4c7e.png)
さらに、VM Trackerからも観察できます。 VMTrackerのSnapshotsを開きます。
![13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/588572f0-174c-6979-27b8-ced36a2ab114.png)
このように、400MBの詳細な割り当て情報を確認できます。
![14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/3d952213-eafa-269f-e482-097e137f31fe.png)
プログラムの他の部分もメモリを適用する必要があるため、Virutal Sizeは400MBよりわずかに大きいことがわかります。400MBはそれぞれResidentとSwappedに格納されます。Resident部分は基本的にDirty Sizeと同じであり、スペースのこの部分がDirtyとしてマークされ、スワップアウトできないことを示します。残りの約240MBは、使用するのに十分な物理スペースがあることを保証するために、一時的にスワップアウトできます。これは、スペースのこの部分を申し込み、特定の賦値の初期化と使用を実行しなかったためでもあります。
賦値が使用された場合はどうなりますか？コードテストを修正して、
![15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/15e78765-afc7-ecd8-bbf3-7e7756824f43.png)
Instrumentsを実行した後に観察します。
![16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/2f2c0325-3a67-a2b3-12ab-faeafbadc3d4.png)
この400MBはすべてDirty Size内にあることがはっきりとわかります。この状況は本当に、このAppとiOSにメモリストレスをかけます。
推奨読書：
[《写给Unity开发者的iOS内存调试指南》（中国語注意）](https://zhuanlan.zhihu.com/p/87310853)
[《Understanding iOS Memory (WiP)》](https://docs.google.com/document/d/1J5wbf0Q2KWEoerfFzVcwXk09dV_l1AXJHREIKUjnh3c/edit)

---
##Addressable
**Q：关于Addressable v1.11.2开始编辑器在“Fast Mode”模式下运行会获取SubAsset失败的问题。**

>A：今日は、Addressablesシステムを使用してプロジェクトを1.8.4から1.14.2にアップグレードしました。AssetReferenceが指すアセットがインスタンス化する時、常に現れた「無効なKey」エラーに気づきました。調査の結果、1.11.2から、FastModeをさらに加速するために、公式によってプロセスの修正が行われたと発見しました。

>以前のバージョンでは、たとえ「Fast Mode」であってもBuildが必要であり、Buildによって生成されたCatalogがPlay時に読み取られました。Catalogは、すべてのAssetEntryとSubAssetをシリアル化し、ResourceLocationMapオブジェクトを生成してから検索します。SubAssetを指すため、多くのAssetReferenceが使用されています。現時点では問題ありません。

>バージョン1.11.2以降、Fast Modeは、Catalogファイルパスではなく、エディター環境でAddressableAssetSettingsオブジェクトのGUIDを直接提供します。したがって、FastMode専用の初期化操作は、Play後の初期化中に有効になります。この時に、ResourceLocationMapではなく、AddressableAssetSettingsLocatorが生成されました。このLocatorは、 エディターGroupウィンドウが対応する表示可能なGroup内のAssetEntryをトラバースしただけで、AssetEntry内のSubAssetはトラバースされないため、ゲームでSubAssetを使用すると、無効なKeyエラーが報告されます。
![17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/455c320f-68cf-493a-29eb-a5c02f5cd6e9.png)
>**公式Changelog：**
>Refactored Play Mode Script for "Use Asset Database" to pull data directly from the settings. This reduces the time needed to enter play mode.

>**提案：**
>1、一時的にv1.8.4バージョンのみを使用します（プロジェクトに長く使用され、比較的安定しています）
>2、1.9.2から1.11.2までのバージョンの使用はお勧めしません。他のbugもあります。
>3、最新の状況にアップグレードし、Simulate Groupsを使用して開発します
>4、公式からの改善を待ちます


##Rendering
**UnityでUV2（Generate Lightmap UVs）を自動展開すると、個別のオブジェクトのMesh内の頂点の数が増加します。**

**自動的に展開した地面の場合、頂点の数が134から136に変更されました。UV2を展開しないなら問題ありません。頂点の数を増やさずにUV2を展開する方法はありますか？**
![18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/a8ae4d67-49e1-17e2-b589-30dce30c8f68.png)
**FBXモデルをインポートする場合、「Meshを最適化する」およびその他の頂点に影響を与えるオプションを選択されていません。**
![19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/a86de129-2ada-8fae-d51c-2db657f9510a.png)
>A：2つのメッシュがLightmapの2つの不連続領域に対応する場合があり、2つのメッシュに頂点が共有される可能性があるため、2つの頂点に分割する必要があります。他のデータは同じですが、UV2が異なります。これは正常です。

>頂点を増加させたくないなら、アーティストが手動でUV2を設定してエクスポートする限り実現可能です。それでも、モデルが一部のメッシュは囲まれて閉じている場合、頂点が重ならないことを保証するのは難しいです。実際、現時点では、頂点はすでにMayaなどのツールに追加してエクスポートされました。Unityに変化が見えないかもしれません。

---

##Build
**Q：Unityエディターでコードのコンパイル速度を向上させる方法はありますか？現在コードを変更するたびに、コンパイルの待機時間は30分近くになります。**

>	A1：大規模なプロジェクトにとって、これは確かに頻繁に遭遇する状況です。一般的に、UnityEditorはスクリプトの依存関係に従ってコードをコンパイルします。これは主に次の4つのステップに分けられます。

>	1、Standard Assets、Pro Standard AssetsとPluginsフォルダーにあるRuntime Scriptをコンパイルします。
>	2、上記の3つのフォルダーにおけるEditorフォルダーの下にあるScriptをコンパイルします。
>	3、プロジェクト内の残りのすべてのRuntime Script（Editorフォルダー以外のScript）をコンパイルします。
>	4、残りのScript（つまり、Editorフォルダー内のScript）をコンパイルします。

>	Unityエディターのスクリプトコンパイル機能を理解した後、開発チームは、長期間変更する必要のないいくつかのスクリプトコード（例えば、さまざまなプラグインコードなど）をStandard Assets、Pro Standard Assets またはPluginsフォルダーに入れることをお勧めします。これなら、これらのコードは一度だけコンパイルする必要があり、その後の時間を節約できます。

>	あるテストでは、プロジェクトで上記の変更を行った後、元のプロジェクトのコンパイル時間が23秒から7秒に短縮されました。これはかなりチームのコンパイル時間を節約します。


>A2：アセンブリ定義を追加します：
>	https://docs.unity.cn/cn/2020.2/Manual/ScriptCompilationAssemblyDefinitionFiles.html（中国語注意）

>A3：プロジェクトを分割し、異なるDLLにコンパイルします。Unity2017以降、エンジン付きのツールを使用して、さまざまなプロジェクトに定義できます。

---

##Rendering
**Q：Pixel Contextが灰色です：**
![20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/1aa516af-4def-ea33-914d-235ea8b0c072.png)
**Debug Vertexも灰色です。**
![21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/b729e937-b4bf-95e4-5a34-a8fae2947874.png)
**これはなぜでしょうか？**

>A1：ピクセルデバッグ用のShaderに＃pragmaenable_d3d11_debug_symbolsを追加します。

>A2：公式ドキュメントには、D3D11またはD3D12でしかデバッグできないと記載されています。
https://renderdoc.org/docs/how/how_debug_shader.html#hlsl-debugging
![22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/036a7f1e-501b-ef1e-f975-9a4649614e0d.png)

---
UWA Technologyは、モバイル/VRなど様々なゲーム開発者向け、**パフォーマンス分析**と**最適化ソリューション**及び**コンサルティングサービス**を提供している会社でございます。

今なら、UWA GOTローカルツールが**15日間に無償試用**できます！！
よければ、ぜひ！

UWA公式サイト：https://jp.uwa4d.com
UWA GOT OnlineレポートDemo：https://jp.uwa4d.com/u/got/demo.html
UWA公式ブログ：https://blog.jp.uwa4d.com