PerformanceTuningC#を使ったUnity開発で無駄なGCを防ぐためにUpdate内でやるべきじゃないことをまとめました。参考Unity2018.4.0気を付けるべきことは大きく分けて二つUnityでは、使わなくなったメモリをGCを使って解放します。この処理は結構重く、さらに処理している間動作が止まるので頻繁にGCが走ることは避けなければいけません。light11.hatenadiary.comGCが発生する要因は様々ですが、特にUpdateのように頻繁によばれる処理の書き方が悪いと発生しやすくなります。そこでこの記事では無駄にGCを走らせないように気を付けるべきことを紹介します。気を付けるべきことは本質的には大きく分けて次の二つとなります。Update内で関数内で一時的な参照型をなるべく生成しないことUpdate内で値型のボックス化を避けること以下、これらについて具体的なテクニックをまとめていきます。要素が最大いくつになるのかわからないのでとりあえずデフォルトの要素数分のメモリを確保します。要素数がこの個数を超えると、新しくCollectionを作ってそちらに中身をコピーします。pro.art55.jpこれはメモリ的にも処理的にも非効率なので避けるべきです。要素の最大数がある程度決まっている場合にはこれをコンストラクタで指定しておくと良さそうです。System.Collections.Generic.List<int>(100);一時的なCollectionであってもグローバル変数にして使いまわす一時的な処理のためにCollectionをローカル変数で定義することはよくあります。}}これはもちろんメモリアロケーションを発生させてしまいます。このようなケースではグローバル変数としてCollectionを定義してそれを使いまわすことでアロケーションを回避できます。}}空配列を返すような実装は控える次の例のように、バリデーションを通過できなかった場合には空配列を返すような実装をすることがあると思います。}}実はこのような空配列の生成もメモリアロケーションを発生させます。これも前節のように空配列のグローバル変数を定義しておくことで回避できます。}}匿名メソッドはOKだけどクロージャはダメC#ではラムダ式を使って匿名メソッドが作れます。}}上記の例は特に問題ありません。この匿名メソッド内でローカル変数を使用した場合、メモリの割り当てが発生するようになります。このようにローカル変数を使用する匿名メソッドを特にクロージャと呼びます。}}基本的に頻繁に呼ばれる処理内ではクロージャは避けるべきです。ちなみにUnityで使えるのはもう少し先になるとは思いますが、C#8からはクロージャを防げる静的ローカル関数という仕組みが導入されたようです。ufcpp.net固定文字列はグローバル変数、可変文字列はStringBuilderで文字列は参照型なので生成すると普通にアロケーションが発生します。次の例のような書き方でも、参照型のローカル変数をnewしているのと同等の処理になります。}}また文字列型は一度作ると内容を変更できません。下記のように書くと一見内容を書き換えているように見えますが、実は新しくインスタンスを生成しているだけです。"b";このようなことから文字列は、それが固定のものであればできる限りグローバル変数にするべきです。動的に変更するようなものにはStringBuilderを使うことで無駄なアロケーションを回避できます。light11.hatenadiary.com値型をobject型に変換するとボックス化するさて値型のローカル変数はスタックに積まれるのでメモリアロケーションは発生しません。値型はobject型に変換できます。object型は参照型なので、これに変換するとメモリアロケーションが発生してしまいます。}}特にジェネリックを使った設計をしているとついやってしまいがちなので注意が必要です。ちなみにボックス化については下記の記事で非常にわかりやすく解説されていますので必要に応じて参照してください。ufcpp.netProfilerでメモリアロケーションを見る方法UnityのProfilerにはメモリアロケーションを見る方法が用意されています。Update関数で不要なアロケーションがされていないかを見るときにはこれを使うと便利です。»プロフィールUnityエンジニア。グラフィックスへの興味が強めです。Blur(渦巻ブラー)のポストエフェクトを実装する月別アーカイブはてなブログをはじめよう!halya_11さんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。