ワーキングメモリ

Windows Mobile 5.0最大の特徴は、「ストレージを不揮発メモリに持つことができる」ということだと思っていたのですが、これって、あまり知られていないことなのでしょうか……。
WindowsMobile2002以前はストレージだろうがなんだろうが全部を揮発性RAMに持って、たくさんのデータを使わない向きにはワーキングメモリをたくさん持たせるという選択も取れたのだと思います。このころの記憶が残っている人からすると、「W-ZERO3はメモリがたくさんあるはずなのにスライダで選べないから使えない」という話になるのでしょうが、そもそもメモリの種類が違うのでは、スライダも何もなぁ。
ただ、これは完全に電池が切れちゃったときにはストレージの中身も一緒に消えるという不安定さとの引き換えだったとは思います。まぁ、よっぽどやばいことにならない限りは、完全に電池がなくなることはないでしょうし、少なくともPCの周辺機器として使用している限りは実用上はあまり問題はないとは思います。
もっとも、W-ZERO3の開発当時のシャープいわく、「ストレージを不揮発メモリに持てるようになってやっと、WindowsMobileを採用できるようになった」とのことなので、PCの周辺機器ではなく、スタンドアローンの端末とW-ZERO3をみなしてたんだなーってスタンスはおぼろげながら見えてきます。電池が消えるだけでフルリセットしてしまう携帯電話ってのはたしかに実用には耐えないでしょうしね。


それはさておき。
WindowsCEカーネルをきちんと追いかけていないのであまり自信はないのですが、たぶんWindowsCEで、ストレージが不揮発性RAMにある機器の動きってこんな風になってるんじゃなかろうかと推測しています。

  1. プロセス起動時に、プロセスごとにメモリ空間を割り当てる
  2. コードの領域はメモリ空間上では固定。ついでに、書き換え不可。
  3. コードの領域は特定のメモリブロックにアクセスしたときにそのメモリブロックに当たる部分をストレージから物理メモリにロードし、メモリブロックに割り当てる(オンデマンドページング)。巨大なコードのプログラムであっても、少ないメモリで実行可能。
  4. ヒープとスタックは常に物理メモリに持ち続ける。

で、ヒープとスタックの領域がどんどん増えていって、実メモリの残りが少なくなるにつれて、「コードをロードしておくメモリブロック」がどんどん減っていき、それによってコードのキャッシュができなくなり、たとえば相対ジャンプしたり、コンテクストスイッチが起こるたびにページングが発生して、結果として重くなってくんじゃないかと。
あくまで推測です。実行中のDLLや実行ファイルにロックをかけがちな傾向や、断片的なMSDNの記述から、こうなんじゃないかなー、と。きちんと試したことないですが、WindowsCEって、「自己書き換え」もできないっぽいですし。
だとすると、ワーキングメモリを見かけ上増やすにはヒープやスタックをスワップアウトさせるようなメモリマネージメントドライバが必要になるって感じですかね。
あー、もう完全にカーネルモードドライバですな。推測が正しいのであれば「仮想メモリアプリ」は実現するのは難しいんじゃないかと。


とはいえ。
実はまじめに作られたWindowsMobileのアプリは、メモリがひっ迫したときには「自前でスワップアウトして、物理メモリを空けなくてはならない」という変なメッセージが飛んできますので、これにみんながみんな対応しているのであれば少しはましになるはずです。
ただ、まじめに対応するのはすごーく大変なんですけどね、これ。拙作NotepadWMでは、このメッセージがきた後あたりからOS自体が不安定になることに気づいたので、スワップアウトどころかアプリ全体を落とす方針で動いています。
そもそも、WindowsMobileのアプリって「いつの間にか勝手に終了している」という傾向がありますが、特に終了するタイミングとして、「メモリが足りなくなったのでカーネルに泣きつかれた」というトリガーが結構多いです。
もっとも、どれだけ個々のアプリが努力しようが、単体で山のようにメモリを食うもの(念のため、WindowsCEはどうせたいしてヒープを取れませんが)や、意地でも落ちないアプリがあったりするとどうにもならないんですけどねー。