お世話になっております。
BehaviourTreeによる制御を行った後のメモリ使用について質問です。
BehaviourTreeコンポーネントを含むGameObjectが破棄された後にMemoryProfilerでキャプチャをしたところ、破棄されたはずのコンポーネントがメモリに残り続ける現象を確認しています。
このコンポーネントがどこから参照されているかMemoryProfilerで確認したところ、最終的にArborのNodeで参照されているようです。
Calculator等ノードの入出力となったコンポーネントがstatic変数のようなもので参照され続けており、GCで破棄されない可能性を検討しています。
この現象はArborの仕様もしくは不具合でしょうか。
こちらの実装の問題かどうか切り分けを行いたく質問させていただきました。
仕様の場合は回避策があればご教授いただけますと幸いです。
ご確認よろしくお願いします。
BehaviourTreeコンポーネントを破棄した後も意図せずメモリに残り続けているコンポーネントがある
Forum rules
Here is the forum to do the questions about how to use to Arbor developer.
Attention point:
ここは、Arbor開発者へ使い方に関する質問を行うフォーラムです。
注意点:
Here is the forum to do the questions about how to use to Arbor developer.
Attention point:
- We can not answer your questions about your project specific issues.
- We can not answer your questions on Unity's specification issues.
- For problems that occur when combined with other assets, please contact us only if the problem is due to an issue on the Arbor side and we need to resolve it in advance.
- Please check Arbor Documentation and ask a question if you still don't know how to use it. If the desired function is not described in the document, it is highly possible that the function does not exist from the beginning, so go to the request forum.
ここは、Arbor開発者へ使い方に関する質問を行うフォーラムです。
注意点:
- ユーザー様のプロジェクトの仕様上の問題や設計に対する質問には答えられません。
- Unityの仕様上の問題に対する質問には答えられません。
- 他アセットとの組み合わせによって発生する問題は、事前に問題を切り分けたうえでArbor側の問題により対応が必要である場合のみお問い合わせください
- Arbor Documentationを確認の上、それでも使い方がわからない場合にご質問ください。欲しい機能の記載がドキュメントにない場合は機能が元から存在しない可能性が高いので要望フォーラムへ。
- caitsithware
- 管理人
- Posts: 503
- Joined: 2015/08/17 12:41
Re: BehaviourTreeコンポーネントを破棄した後も意図せずメモリに残り続けているコンポーネントがある
まずコンポーネントがNodeBehaviour関連の場合についてです。
最初に考えられるのは、エディタ上でノードなどをコピーした場合です。
この場合はクリップボードのような内部データにコンポーネントそのものがコピーされていますのでコピー元が破棄されても残ります。
またNodeBehaviourのフィールドから参照しているコンポーネントもGCの対象から外れます。
こちらについては仕様であり、ランタイムへの影響もありませんのでそのままでも問題ないかと思います。
エディタ操作に関係なくビルドしたランタイムでも残る場合はArbor3の何らかのキャッシュの不具合の可能性が高いです。
ざっと調べてみたところ問題がありそうな箇所がありますので今後の更新で対応いたします。
暫定対処方法
NodeBehaviour関連以外の場合は特にキャッシュは行っていないと思いますが、すべてを調査する必要がありますので現時点では分かりません。
Arborが原因でキャッシュされていると思われる箇所の情報などが他にありましたらご報告いただけると助かります。
最初に考えられるのは、エディタ上でノードなどをコピーした場合です。
この場合はクリップボードのような内部データにコンポーネントそのものがコピーされていますのでコピー元が破棄されても残ります。
またNodeBehaviourのフィールドから参照しているコンポーネントもGCの対象から外れます。
こちらについては仕様であり、ランタイムへの影響もありませんのでそのままでも問題ないかと思います。
エディタ操作に関係なくビルドしたランタイムでも残る場合はArbor3の何らかのキャッシュの不具合の可能性が高いです。
ざっと調べてみたところ問題がありそうな箇所がありますので今後の更新で対応いたします。
暫定対処方法
- Assets/Plugins/Arbor/Internal/Scripts/EachField.csを開く
- 686行目(メソッド内の一番最後の行)に以下のコードを追加
Code: Select all
s_FindReceiver.receiver = null;
NodeBehaviour関連以外の場合は特にキャッシュは行っていないと思いますが、すべてを調査する必要がありますので現時点では分かりません。
Arborが原因でキャッシュされていると思われる箇所の情報などが他にありましたらご報告いただけると助かります。
Re: BehaviourTreeコンポーネントを破棄した後も意図せずメモリに残り続けているコンポーネントがある
ご連絡ありがとうございます。
報告した現象はランタイムで確認しております。
こちらで確認した限りではCalculatorやDecoratorの入出力となったコンポーネントが残っており、NodeBehaviour関連である可能性が高いと推測します。
こちらでもEachField.csやCalculator.csのstatic変数にあたりを付け調査を行っていますが、特定には至っておりません。
いただいた暫定対処方法で改善するか確認いたします。
引き続きよろしくお願いします。
報告した現象はランタイムで確認しております。
こちらで確認した限りではCalculatorやDecoratorの入出力となったコンポーネントが残っており、NodeBehaviour関連である可能性が高いと推測します。
こちらでもEachField.csやCalculator.csのstatic変数にあたりを付け調査を行っていますが、特定には至っておりません。
いただいた暫定対処方法で改善するか確認いたします。
引き続きよろしくお願いします。
Re: BehaviourTreeコンポーネントを破棄した後も意図せずメモリに残り続けているコンポーネントがある
暫定対処を試しましたが、NullExceptionが発生&EachField.cs L435にnullチェックを追加しましたが今度はうまくビヘイビアツリーが動作しなくなってしまいました。
メソッドの一番最後に追加とのことでしたが、EachField<T>.Find(object rootObj, System.Type type, IFindReceiver receiver, bool ignoreRoot)の一番最後ということであっていますでしょうか。
引き続き調査しますが、情報ありましたらよろしくお願いいたします。
メソッドの一番最後に追加とのことでしたが、EachField<T>.Find(object rootObj, System.Type type, IFindReceiver receiver, bool ignoreRoot)の一番最後ということであっていますでしょうか。
Code: Select all
s_FindReceiver.receiver = null;
- caitsithware
- 管理人
- Posts: 503
- Joined: 2015/08/17 12:41
Re: BehaviourTreeコンポーネントを破棄した後も意図せずメモリに残り続けているコンポーネントがある
再帰的に呼び出される可能性を失念しており内容が不十分でした。
正確には以下のようなコードにしてください。
正確には以下のようなコードにしてください。
Code: Select all
public static void Find(object rootObj, System.Type type, IFindReceiver receiver, bool ignoreRoot)
{
var oldReceiver = s_FindReceiver.receiver;
s_FindReceiver.receiver = receiver;
s_FindReceiver.Find(rootObj, type, ignoreRoot);
s_FindReceiver.receiver = oldReceiver;
}
- caitsithware
- 管理人
- Posts: 503
- Joined: 2015/08/17 12:41
Re: BehaviourTreeコンポーネントを破棄した後も意図せずメモリに残り続けているコンポーネントがある
もともとのコードもあまり良い作りとは言えない点に加え、別件で報告がありましたInstantiateAsyncで動かない不具合も同じ箇所が関連していますのでここは次回更新であわせて修正いたします。
Re: BehaviourTreeコンポーネントを破棄した後も意図せずメモリに残り続けているコンポーネントがある
ご対応ありがとうございます。
新しくいただいた対応を入れて検証してみましたが、症状は改善しませんでした。
引き続き情報がありましたらよろしくお願いいたします。
アップデートでの対応もお待ちしております。
新しくいただいた対応を入れて検証してみましたが、症状は改善しませんでした。
引き続き情報がありましたらよろしくお願いいたします。
アップデートでの対応もお待ちしております。
- caitsithware
- 管理人
- Posts: 503
- Joined: 2015/08/17 12:41
Re: BehaviourTreeコンポーネントを破棄した後も意図せずメモリに残り続けているコンポーネントがある
ご確認ありがとうございます。
EachFieldの各種Findメソッドでのキャッシュは他にもありますので、そちらも同様の対策が必要なようです。
ひとまずこちらの開発環境(InstantiateAsyncへの対策も行った環境)にて、一通りEachFieldへの対策を行い関連オブジェクトDestroy後にMemoryProfilerを確認したところAll Of MemoryタブのManaged/Managed ObjectsにArbor3関連のコンポーネントのインスタンスが残っていないことを確認いたしました。
次回の更新でこの対応を適用いたします。
EachFieldの各種Findメソッドでのキャッシュは他にもありますので、そちらも同様の対策が必要なようです。
ひとまずこちらの開発環境(InstantiateAsyncへの対策も行った環境)にて、一通りEachFieldへの対策を行い関連オブジェクトDestroy後にMemoryProfilerを確認したところAll Of MemoryタブのManaged/Managed ObjectsにArbor3関連のコンポーネントのインスタンスが残っていないことを確認いたしました。
次回の更新でこの対応を適用いたします。
Re: BehaviourTreeコンポーネントを破棄した後も意図せずメモリに残り続けているコンポーネントがある
ご対応ありがとうございます。
それでは、次回アップデートの反映を検討させていただきます。
引き続きよろしくお願いいたします。
それでは、次回アップデートの反映を検討させていただきます。
引き続きよろしくお願いいたします。
- caitsithware
- 管理人
- Posts: 503
- Joined: 2015/08/17 12:41
Re: BehaviourTreeコンポーネントを破棄した後も意図せずメモリに残り続けているコンポーネントがある
Arbor関連でGCの対象にならずにメモリーに残るかどうかの仕様についてもまとめましたので記載いたします。
残るのが仕様
とくに「破棄されていないArbor関連コンポーネントから参照されているインスタンス」についてはインスタンスが破棄されたかどうかの検出が難しいため、破棄されても残っているのは仕様であり現時点で改善予定はないものとしてご理解ご了承のほどよろしくお願いいたします。
残るのが仕様
- ArborEditorを開いた場合など、エディタ関連で参照されているデータ全般
- 型情報や属性などのキャッシュデータ
- 破棄されていないArbor関連コンポーネントから参照(Parameterやデータフローでの受け渡し含む)されているインスタンス
- 破棄されたArbor関連コンポーネントからのみ参照(Parameterやデータフローでの受け渡し含む)されていたインスタンス
とくに「破棄されていないArbor関連コンポーネントから参照されているインスタンス」についてはインスタンスが破棄されたかどうかの検出が難しいため、破棄されても残っているのは仕様であり現時点で改善予定はないものとしてご理解ご了承のほどよろしくお願いいたします。