2006/12/5

気になったので調べている  VRMスクリプト禅問答
(前略)
メモリリークしないのだろうか?といつも不安になっています。
リカーシブルコールのようなことをしているのですが、指定時間後にVRMビュアーが勝手に呼び出しするだけなのでスタックには積まれないと思っているのですが・・・さて?どうなんでしょうか?

SetEventAfter命令を使った条件成立待ちが、いわゆる再帰呼び出し(リカーシブコール)にならないのは、近ちゃん氏がご自身でおっしゃっている通りで、実はVRM4EGを書く過程でI.MAGiCからも確認が取れているので大丈夫です、多分。

閑話休題。

気になったのは「メモリリーク」について。実績から言うと、この手法を多用する自律自動運転を実装したレイアウトで1時間以上のロングランテストをやったことがあるので、問題ないだろうとは思ってるんですが、まぁ、あくまでも経験則なので、もうちょっと確証が欲しいな、と。

以下、大半のVRMユーザーにはどうでもいい話が続く上、結論は週末まで持ち越します。


*     *     *

まず、VRMビュワーが仮にメモリリークを起こすと仮定して、それが観測可能なのかどうかを確認する必要があります。もし、VRMビュワーが起動時にレイアウトサイズや配置部品数を元に、自分が必要とするメモリ空間を見積もって静的に確保し、以降は内部でメモリ管理をやっているとすると、Windowsからはメモリリークがあるかが原理的にわかりません(デバッガ使えば話は別ですが、REに当たるのでライセンス違反っぽいです)。

これをブラックボックス的に確認するのは難しくありません。まず、レール1本と編成を配置し、タスクマネージャとVRMビュワーを起動します。この時点でビュワーのメモリ使用量をメモしておきます。

次に、この編成に仕様上の限界に当たる255個のグローバル変数を宣言するスクリプトを書き、再度VRMビュワーを起動します。興味のある人は追試してみてください。明らかにビュワーのメモリ使用量が増えたことが確認できます。これで、少なくともVRMビュワーのメモリ使用量がレイアウトサイズ・部品数と一対一対応しないことがわかりました。

次に、VRMビュワーが動的にメモリを確保するかを確認するために、この編成の車両数を限界いっぱいにした上で、キーを押したら1両目を切り離すスクリプトを書きます。Uncouple命令を実行すると編成オブジェクトが複製されますから、255個のグローバル変数を格納すべきメモリ空間が必要になるはずです。で、実際にやってみると編成を分割する毎に一定の割合でメモリ使用量が増加します。つまり、VRMビュワーは動的にWindowsからメモリ空間を確保する、ということです。これが不要になった時点で解放されないと、いわゆるメモリリークと呼ばれる状態になります。

以下は週末に実験するつもりの事項で、まだ確認が取れていません。興味のある人はボクに先行して実験してみてください。可能であればweblogやここのコメント欄などで結果をレポートしてください。

リファレンスを読む限り、VRMスクリプトのメソッドは、VRMビュワーの仮想マシンから見るとクラスにあたり、イベントから駆動される毎にインスタンスとして複製されると考えて良さそうです。メソッド内で大量のローカル変数を宣言すれば、そのサイズはタスクマネージャから観測できる大きさになるでしょう。

そこで、大量のローカル変数を宣言するだけのメソッドを作り、これを複数併走するように実行してやります。メモリ確保と解放が正しくおこなわれていれば、メモリ使用量は、併走するメソッド数に宣言するローカル変数が欲するメモリ領域を乗じたあたりを上限にして安定するはずです。これが時間経過と共に漸増するようであれば、メモリリークを疑う必要がありますね。結果は、後日レポートします。多分、大丈夫だとは思いますが。

*     *     *

さて、本筋からはそれますが。

編成を連結させると、一方の編成が消失したようにビュワー上では見えます。が、実は消失した方の編成のグローバル変数やメソッドにアクセス可能であることは既に報じた通りです。つまり、連結によってビュワー操作からアクセス不能になった編成オブジェクト分のメモリは解放されない、ということです。

従って、編成の分割と連結を然るべくおこなえば、VRMビュワーのメモリ使用量は際限なく増えていくことになります。これを厳密な意味でのメモリリークと呼ぶかは微妙ですが、事実上のメモリリークではあります。これを回避するには、VRMビュワーが定期的に自身の状態を評価し、不必要になったメモリを解放する(または再利用可能な状態にする)仕掛け、すなわちガーベージコレクション(GC)が必要になります。直感的には、現時点でのVRMビュワーには、あらゆる意味でGCは実装されてないっぽいです。と言うのも、だからこそ文字列変数が未サポートなんだろうな、と思うからなんですが。

そして、GCは仮想マシン型の実装の鬼門の1つですから、VRMスクリプトが文字列変数をサポートするようになった暁には、改めてメモリリーク可能性の再評価が必要になることでしょう。っつーか、その初期バージョンは、特に物理メモリ実装の小さい環境での経時パフォーマンスダウンに悩まされたりするかも知れません。
0

コメントを書く

この記事にはコメントを投稿できません




teacup.ブログ “AutoPage”
AutoPage最新お知らせ