UnityUnityのAddressableアセットシステムのメモリ管理の仕組みについてまとめました。参考Unity2019.2.10Addressable1.3.8はじめにこの記事ではAddressableアセットシステムのメモリ管理の仕組みについてまとめます。以下の記事にまとめていますので、必要に応じて参照してください。light11.hatenadiary.comまた、ロードやアンロードの基本的なやり方については以下の記事にまとめています。light11.hatenadiary.com本記事はこれらの知識を前提とします。ロードとリリース(アンロード)をペアにするのが基本さてAddressableは参照カウントでリソースのロード・アンロードを管理しています。Addressables.LoadAssetAsync()などでロードがリクエストされると参照カウントがインクリメントされ、Addressables.Release()などでリリース(アンロード)がリクエストされるとデクリメントされます。参照カウントがデクリメントされるAddressables.Release(handle);そして参照カウントが1以上になった時にアセットがロードされて、0になった時にアンロードされます。以上のことから、当然ですが「ロードしたものは必ずリリースする」というのが大原則となります。明示的にリリースしなくてもUnityが自動でやってくれるケースがあったりするので、このあたりを以下でまとめます。GameObjectの生成方法とメモリ管理2つの生成方法Addressableを使ってGameObjectをインスタンス化する方法は大きく分けて二つあります。一つ目はAddressables.LoadAssetAsync()などを使ってロードした後にGameObject.Instantiate()をする方法です。handle.Task;Instantiate(handle.Result);また二つ目の方法としてAddressables.InstantiateAsync()を使う方法があります。Addressables.InstantiateAsync("Example");メモリのリリース方法の違いさて、Addressables.LoadAssetAsync()を使ってロードを行った場合、Addressables.Release()をすることですべての関連するリソースへの参照カウンタがデクリメントされます。これに対してAddressables.InstantiateAsync()でインスタンス化した場合には、Addressables.ReleaseInstance()を使ってリリース処理を行う必要があります。このメソッドは生成されたインスタンスを破棄しつつ、参照カウンタをデクリメントします。Addressables.InstantiateAsync()で生成した場合、生成されたインスタンスに関連するリソースの寿命は所属するシーンに依存します。Addressables.InstantiateAsync()で生成されたGameObjectが所属するシーンが破棄されると、それに連動してAddressables.ReleaseInstance()と同等のリリース処理が自動的に行われます。ちなみにこのAddressables.ReleaseInstance()の引数にはAsyncOperationHandleかインスタンス自身のどちらかを渡しますが、Addressables.InstantiateAsync()はtrackHandleという引数を持っていて、これにfalseを渡すとAsyncOperationHandleでしかリリースができなくなります。(処理負荷が下がるようですが制御しづらくなるので微妙な感じです)どちらを使えばいいのか?それではGameObjectをインスタンス化する際には上記二つの方法のどちらを使用すればいいのでしょうか。この答えとしては、基本的にはインスタンス化のためのAPIであるAddressables.InstantiateAsync()を使うのがよさそうです。上記のリリース方法の特性をよく理解して使う必要があります。一回Addressables.LoadAssetAsync()を呼んでからGameObject.Instantiate()を数百回呼んだ方が効率が良いようです。シーンのアンロードタイミングAddressableを使う場合、シーンはAddressables.LoadSceneAsync()を使ってロードします。Addressables.LoadSceneAsync("ExampleScene");こうしてロードしたシーンはAddressables.UnloadScene()を使ってアンロードできます。他のシーンをSingleモードで読み込んだ場合には読み込まれる前に存在していたシーンは自動的にアンロードされます。明示的なリリースが行われるまでデータを保持し続けます。よって、不要になった時点でこれらのAsyncOperationHandleに対してAddressables.Release()する必要があります。自動的に解放されるものAddressables.DownloadDependenciesAsync()とかAddressables.UnloadScene()といったメソッドは戻り値としてAsyncOperationHandleを返すものの、AsyncOperationHandle.Resultとして受け取るものがありません。このようなAsyncOperationHandleを返すメソッドにはautoReleaseHandleというが用意されています。これをtrueにすると処理が終わった後にHandleが自動的にリリースされます。Viewerを使用します。これについては以下の記事にまとめていますので、必要に応じて参照してください。1はてなブログをはじめよう!halya_11さんは、はてなブログを使っています。ブログを報告する引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。