2006-07-07 [長年日記]

[Q3] メモリの確保

Windows CEの場合、プロセスごとの仮想メモリ空間が32MBしかないので、普通にメモリを確保すると物理メモリがいくらあっても32Mまでしか使えません。この32MB内に実行ファイルのイメージなども展開されるので使えるメモリはさらに小さくなり、さらにヒープにフラグメントが発生すると連続した大きなメモリを確保するのが困難になります。

この32MB以外の場所のメモリを使うには、メモリマップトファイルを使用するか、VirtualAllocを使います。Windows CEのVirtualAllocは2MB以上のメモリを確保するときに、MEM_RESERVEとPAGE_NOACCESSを指定すると、ラージメモリ領域という件の32MBとは別の領域にメモリを確保できます。確保したメモリはそのままコミットすれば物理メモリが割り当てられて使用できます。ただし、手を抜いていきなりMEM_COMMITを指定すると普通に32MBの空間内にメモリが確保されてしまいます。

というわけで、QMAIL3内部で使っている大きいメモリ用のメモリアロケータでも、2MBよりも大きなメモリを確保するときにはVirtualAllocを使ってラージメモリ領域にメモリを確保するようにしてみました。

[Q3] 大きなメッセージの受信

なぜ上のような変更をしたのかというと、以前からPocket PC版で2MB以上のメッセージを受信できないという話を何度か聞いていたためです。手元にあるsigmarion IIIで試すと10MB位のメッセージまで普通に受信できてしまうので原因が良くわからないのですが、QMAIL3がメッセージを受信するときにメッセージサイズ分のメモリを割り当てるのは確かなので、メモリの確保に失敗しているならば上の変更で違いが現れるかなと思ったからなのです。

ところが、上の変更をしているときに気づいたのですが、同期フィルタで先頭100行だけ同期するようにしている場合でも、メッセージ全体のサイズのメモリを確保するようになってしまっていました。これはこれで問題なので直したのですが、同じ量のメモリを確保していたということは、メモリが確保できないのが原因で受信できないならば同期フィルタを設定してもやはり受信できなかったはずです。

というわけでますます良くわからないことに…新し目のPocket PCをお持ちでテストに協力してくれる方募集中です。

本日のツッコミ(全7件) [ツッコミを入れる]
# エピゼマ (2006-07-10 14:26)

ご無沙汰しています。<br>W-ZERO3に「PocketPC 2003 SE」(スナップショット版)と「WM 5.0版」(Nighty Build)を入れて試してみました。<br>スナップショット版ではダウンロードできなかった約2.5MB のメールが、NBではダウンロードできました。

# snak (2006-07-11 02:05)

報告ありがとうございます。一応ポイントが外れていたわけではなさそうですね。ついでといっては何ですが、スナップショット版の方で、同じメールを「先頭100行のみ」と「先頭1000行のみ」に同期フィルタの設定をしてダウンロードできるかどうか調べてみていただけないでしょうか。

# エピゼマ (2006-07-11 06:44)

スナップショット版での結果です。「先頭100行のみ」「先頭1000行のみ」ともにダウンロードできました。無制限だとやはりダメです。

# snak (2006-07-12 05:18)

早速ありがとうございます。やはり制限するとOKなんですね。謎です…<br><br>ちなみに、駄目なときはどの時点で駄目になるのでしょうか。例えば、同期ダイアログで右側のプログレスバーが伸びる前にエラーになるのでしょうか。もしくは、伸びきった後でエラーになるのでしょうか。<br><br>それと、メッセージボックスの形式(一メッセージ一ファイルか、全体で一ファイルか、後者の場合には分割しているか、など)を教えていただけないでしょうか。

# エピゼマ (2006-07-14 11:22)

エラーが発生するのは、当該メールの受信が始まってプログレスバーが最後まで到達した後です。「POP3エラー(0x000D0800) RETRコマンドでエラーが発生しました。不明なエラーです。」と表示されます。これより後にあるメールも受信できません。<br><br>メッセージボックスは1MBで分割、インデックスブロックサイズは指定していません(デフォルトのまま(ゼロ)です)。

# エピゼマ (2006-07-14 11:30)

メッセージボックスを、1ファイル/msgに変更してみましたが、結果は同様でした。

# snak (2006-07-18 15:06)

ありがとうございます。<br><br>色々と調べてみたところ、状況によっては最初に確保したメモリでは足りなくなってしまうケースがありそうです。その場合に、追加でメモリを確保するときにさらに大きなメモリを確保しようとするので、そのときにエラーになっているようです。<br><br>今回の変更でメモリ自体が確保できないケースは減りそうですが、いずれにしても無駄なので最初にメモリを確保するときにもう少し余裕を持って確保するようにして、上記のようなケースが発生しないようにしておきました。


トップ «前の日記(2006-07-06) 最新 次の日記(2006-07-08)»