ゲーム開発ではよくある話ですが、RPGツクールMVにも時々メモリリークの話が話題となります。
本体に関するメモリリークはバージョンアップでの改良を期待したいところですが、
残念ながら各種プラグインでメモリリークをしている事がたまにあり、そのようなものはこちらで調査・パッチを当ててあげた方が早いケースも存在します。
ここではその原因の調べ方を記述します。
メモリリークが起きると何が起きるの?
メモリリークは、解放されず使用されないメモリが蓄積されていき、使用メモリがどんどん増えていくことを指します。
ちょっとしたメモリリークであればゲームに支障が出ませんが、ある一定以上メモリが蓄積されると、ブラウザや見てるページがクラッシュします。
RPGツクールMVの場合、クラッシュはゲームの強制中断を示し、セーブデータ箇所からプレイのやり直しになるため、遊ぶのがとても辛いです。
今回はそのようなメモリを大量に消費してクラッシュするような、困ったメモリリーク、メモリブロートについて調べていきます。
再現条件を調べる
実際にメモリリークがしている事が分かったら、いつメモリリークしてるのかを調べましょう。
よくあるパターンとしては以下のパターンを調べると、メモリの蓄積がされやすいでしょう。
再現する条件を特定し、再現性を高めるのは、原因を調査する上でとても重要です。
- シーン移動系
- マップ移動(別の画面に移動する操作)を100回繰り返す
- 2つのマップを交互に往復する
- 色んなマップを移動する
- メニューを100回出し閉じする(Esc連打する)
- 1000歩、歩く
- 100回バトルする
- 単調な攻撃パターンを繰り返す
- 魔法攻撃を繰り返す
- たくさん画像を読み込ませる
- マップ移動(別の画面に移動する操作)を100回繰り返す
- 会話ウィンドウ系
- 100回会話ウィンドウを出す
- とにかく会話させる
- 探索系のゲームの場合、アイテムを調べまくる
- 100回会話ウィンドウを出す
- セーブ系
- セーブを100回繰り返す
- コンティニューを100回繰り返す
こんなことをしまくってると、メモリリークするゲームはメモリリークするでしょうし、クラッシュするゲームはクラッシュするでしょう。
最初は面倒くさいので、ただゲームを進行させてプレイを進めるだけでもいいと思います。
デベロッパーツールの静的解析で、メモリの使用量を調べる
(検証のために、適当なゲームを作成し、意図的にメモリリークするようなコードをプラグインに仕込んでゲームを起動しています。ユーザーアクションの度に、大量にメモリが確保されるようにしてみました。)
Chromeのデベロッパーツールを使って調査をするため、ゲームはChromeを使って進めましょう。
Windows
ではF12
を押してデベロッパーツールを開き、[Profiles]
をクリックして下さい。
[Take Heap Snapshot]
で、実際にメモリがどのように使われてるかを調べることが出来ます。
[Take Snapshot]
をクリックしてみましょう。メモリ使用量が左に表示されます。
二回目からは、左上の●をクリックするとSnapShotが取れます。
上の画像では、ゲーム開始直後にスナップショットを取ったのが、Snapshot1
です。
その後ゲームを進めつつSnapshot4
まで複数回取ってみました。
ゲームを進行するだけで、40MB以上もメモリ使用量が増えてることがわかります。
実際に問題となる箇所を調べる。
この解析結果を見るに、1行目の(closure)
が61MBもメモリを使用していることがわかります。
各欄はクリックして詳細を開く事で、メモリを沢山使用している場所を調査できます。
同一の変数名のインスタンスがたくさん出てきました。
(最初に自分でメモリリークを仕込んでいた通りの結果が、確認できました。)
またこのインスタンスはsceneクラスのインスタンスを開放せずに持っていることが、ここから確認出来ます。
後は、問題となる変数名が分かれば、コードと照らし合わせれば、それがどこのコードのメモリリークなのか、強力な手がかりとなるでしょう。
ツクール本体や、プラグインも含め、全てのコードから検索(grep)しましょう。
原因が分かったら、報告をする・パッチを当てる・プラグインを外すなどしてみて、同じことを試してみましょう。
調べた再現条件で再現しなくなれば、メモリリークが解決したということです。
おめでとうございます!
以上となります。
なお、今回は静的な解析方法での話をしましたが、動的にメモリリークを調べることもChromeデベロッパーツールは可能です。
臨機応変に使用してみて下さい。