« EGLImageKHR を使うテクスチャの高速書き換えはハードル高い | メイン | RenderScript + Java で waifu2x を実装した »

2015年06月12日

吉里吉里Z 開発:: メモリの断片化によるメモリ確保失敗に関して

    

最近話題に上がっていたので、詳しい説明を書く。

メモリが確保される状況を図にして説明する。

memory_fragment.png

上図は、Bitmap 等大きなメモリを4回確保した後、3個目オレンジのメモリを解放(1,2,3,4)。
スクリプトの変数等の小さいメモリを確保(5)。
2個目紫を解放して、スクリプトの変数等を確保(6)。
1個目青を解放して、スクリプトの変数等を確保(7)。
Bitmap 等大きなメモリ(黄色)を確保(8)。
と言ったメモリ確保の流れを図示している。

こうなった状態で再度Bitmap 等大きなメモリを確保しようとしたら確保できなくなる。
図では13個開いているので、5個のメモリは確保できるはずだが、連続した領域として確保できないので、確保に失敗する。
図の確保順はメモリ管理アルゴリズムがファーストフィットの場合で、ベストフィットだったとしたら6の段階で紫があった位置ではなく、オレンジがあったところ、緑の右隣が確保され、紫のところは5個の連続した領域が残ることになる(図の 6')。
ファーストフィットは一番最初に見つかった確保可能な領域を使用するもので、ベストフィットは空き領域の中で欲しいサイズ以上の出来るだけ近いサイズの領域を使う。
ファーストフィットは、最初に見つかった領域を使うので早くメモリ確保できるが、ベストフィットは空き領域のリストを全部調べるので少し処理時間が延びる。
ただし、ベストフィットの方がフラグメンテーションが起きづらい(6',7',8')。
8' の後もメモリ確保が出来る。
ただ、フラグメンテーションが置きづらいと言っても、確保のされ方によっては断片化が起きる。

以上がフラグメンテーションが起きてメモリが確保できなくなる理由や、メモリ管理アルゴリズムによって差が出る理由。

吉里吉里2 と吉里吉里Z で Bitmap メモリが確保できないと言うエラーが出る率が違うのは、メモリ管理アルゴリズムの差によるものと思われる。
Windows Vista 以降ではフラグメンテーションが起きづらいアルゴリズムが採用され、吉里吉里Z ではその恩恵を受け、吉里吉里2 は C++Builder のメモリ管理アルゴリズムが使われフラグメンテーションが起きやすいのではないかと推測される。

図では、緑のセルは解放されていないが、実際は確保されたり解放されたりする。
例えば、7の段階で紫だった位置の緑のセルが解放されれば間に連続した空き領域が出来る。
厳密には、分断された状態で空き領域のリストが保持されているので、コンパクションと言われる連続した空き領域をひとまとめにする処理を行わなければ大きな連続した空き領域にはならない。
つまり、ずっと確保されたままにならず、メモリ コンパクションが行われるのならフラグメンテーションの影響でメモリが確保できなくなることはない。

KAG3 では、既読判定のためラベル通過ごとに変数が増える。
また、その変数はロードし直したりしなければ、ずっと確保されたままになり、定期的にメモリ確保が発生するので、メモリのフラグメンテーションが発生しやすい。
確保されたままであれば、コンパクションの意味はないので、メモリ管理アルゴリズムによっては早い内にメモリ確保に失敗する状況が発生しうる。
ベストフィットなどのアルゴリズムであれば、そうそう確保に失敗する状況にはならない。
どれぐらいの規模(連続したプレイ)で「ビットマップ用メモリを確保できません/……」と言ったエラーが発生するのかはわからないが、シナリオが長くなり、画像サイズが大きくなってきたことで、この問題が顕在化しやすくなっているのではないかと思われる。

吉里吉里Z では、この問題は発生しづらくなっているとはいえ、発生しないわけではない。
そこで、さらに発生する率を減らすため、Bitmap を確保するメモリ領域を分離する設定がある(デフォルトは有効にはなっていない)。
Bitmap のような大きな領域とその他の小領域のメモリ領域を分離すると、大きな領域を解放後の領域に小さいメモリ確保が発生することがないので、フラグメンテーションの発生が少なくなる。
また、Bitmap の領域を分離するとともに、Bitmap の領域解放後は毎回メモリのコンパクションも行っているので、常に連続した大きな領域が開いている状態を維持しようとしている。
この辺りの設定などについては、以下のエントリーに書いている。

メモリ断片化低減対策
グローバルヒープもHeapCompact可能に


投稿者 Takenori : 2015年06月12日 21:04




comments powered by Disqus
Total : Today : Yesterday : なかのひと