C++版にはLive2Dの内部で確保したメモリに関して、リークしているかどうかを検出する機能があります。 具体的にはinit()からdispose()までにLive2Dが確保したメモリについての情報をダンプします。 ※ この機能はDEBUGビルド時しか機能しません。 ( VisualStudioなら_DEBUG、XCodeならDEBUGマクロが有効の時) 例 //initを呼ぶ前にフラグを設定します。 UtDebug::addMemoryDebugFlags( UtDebug::MEMORY_DEBUG_MEMORY_INFO_COUNT ) ; Live2D::init( ); /***** モデルやモーションの生成、破棄 *****/ Live2D::dispose();//この時にメモリ情報を表示します。 出力例 ----------------- Live2D Memory Info ----------------- Successfully cleaned (no memory leaks found). local malloc count : remaining : 0 local malloc count : total : 48884 local malloc memory : current : 0 byte local malloc memory : peak : 539 KB local malloc memory : total : 1351 KB allocator malloc count : remaining : 0 allocator malloc count : total : 109 allocator malloc memory : current : 0 byte allocator malloc memory : peak : 604 KB allocator malloc memory : total : 802 KB LDObject instance count : 1 LDObject total count : 47303 LDUnmanagedObject instance count : 0 LDUnmanagedObject total count : 1 ------------------------------------------------------ 出力のうち重要なのは local malloc count : remainingと allocator malloc count : remaining の項目です。 これらが0になっていない場合はLive2D関連のオブジェクトの解放忘れがあります。 Live2Dのメモリ構造について Live2D SDKの仕様として、モデルやモーション間でID情報は共有する構造になっています。 新しいモデル(またはモーション)を読み込んだ際、これまで1度も使われていないIDの場合は新たにIDを保持します。 モデル(モーション)を破棄した後も元のサイズには戻らずリークした印象となります。 同じモデルをロード・削除する度にメモリ使用量が増える場合はメモリリークと思われますが、初回ロード時しかメモリが増えない場合それは正常な動作となります。 また、事前にモデル・モーションでのIDの使用数が推測しにくく、ダウンロードによる新規モデル追加などのケースも有り得るため 現状では大きめに確保するよりは、必要に応じて確保する方式を採っています。 Live2D内部のメモリ管理では、共通領域、各モデル、各モーション、それぞれに異なる領域にまとめてデータを確保・破棄していく事で断片化が発生しにくい仕組みになっています。 modelAとmodelBの2つがいた場合、modelAのメモリ領域は、modelB のメモリ領域と完全に分離されています。 modelAを破棄した際は、modelAに使われていたメモリ領域が完全に再利用可能になります。 modelA 1つが利用するメモリ領域も単一の連続領域で確保するのではなく、複数のページ(最低4KBのまとまったメモリ領域)で構成されております。 各ページから実際のポインタサイズに応じて分割利用します。 より大きなメモリを使用するmodelCを後からロードする場合も、より小さなmodelAのメモリ領域を再利用しつつ、足りない分だけページを確保してロード可能となります。 |