翻訳:Compact Frameworkでメモリを操作する効率的な方法

元の記事はロブティファニーのブログにあります。



ドライバー、プログラム、居住者、さらにはWindowsのために640KB以上を圧縮しようとして時間を費やしたDOSの古き良き時代を覚えている人はいますか? QEMM、HIMEM、EMM386.EXEのようなものは、私から暖かい思い出を呼び起こします。







画像



私たちの中には、DOSセッションに740Kbを割り当て、プリエンプティブマルチタスクを提供するOS / 2に取り組んだ人もいました。 はい、問題なく複数のDOSゲームを異なるウィンドウで同時に実行できました。 驚いたことに、クラッシュ保護されたスロットがたくさんあり、それぞれに独自の740 KBのメモリがありました。









今日戻ってくると、Windows CE 5.0とWindows Mobile 6.xは、80年代と90年代のgreat祖父といくつかの類似点があることがわかります。 Windows Phoneの管理を信頼する32ビットの組み込みオペレーティングシステムは、多数のスロットで構成されていますが、640KbのDOSとは異なり、アプリケーションは32MBの仮想メモリを受け取ります。 ただし、DOSと同じように、アドレス空間全体にアクセスすることはできません。これは、システムライブラリなどの他のものがすでにこの空間を使用しているためです。





私は最近、友人であるグレンジョーンズに出会いました。 グレンと彼の同僚が世界で最高のコンパクトフレームワーク開発者の一人であると考えるだけではないことに留意してください。 彼のチームは、コンパクトフレームワークを使用して、Windows Mobile上で実行される最大かつ最も複雑なアプリケーションの1つを設計および開発しました。 巨大なWindows Mobileアプリケーションを開発している他の企業と同様に、メモリ不足の問題は解決しませんでした。 「ドリームチーム」のアーキテクトの1人であるブライアンパイクは、空のexeファイルをメモリに保存し、フォーム、コード、リソース、およびデータを個別のマネージアセンブリに保存すると、使用される仮想メモリの量が減少することを最近発見しましたスロット、同時に1GBの共有メモリ内でスロット外のメモリを使用する機会を得ます。





この驚くべき発見をよりよく理解するために、2つの異なる方法で実行されている管理対象アプリケーションのメモリマップを示す2つの図を示します。 下に表示されるエミュレータで実行されているアプリケーションは、32個の共有仮想メモリスロットの使用を表示します:赤は空きメモリ、青は使用済みメモリ、緑は予約済みメモリを示します。 スロット1はシステムライブラリでいっぱいであり、後続の各スロットには小さな青い領域があることに気づかずにはいられません。 このスペースは、システムおよび管理ライブラリによって使用されます。つまり、正直な32メガバイトを取得できません。



左側には、スロット番号14で実行されているCompact FrameworkアプリケーションStandardExe.exeがあります。 このシンプルなマネージアプリケーションには、リソースとしての2.25MBビットマップと、このビットマップが存在するフォームが含まれています。 よく見ると、2.25の青いメガバイトがスロット14の一番下にあることがわかります。 これは、exeファイルが占めるスペースです。

標準的な方法最適化された方法





右側には、スロット番号11で実行されているOptimizedExe.exeがあります。 これは完全に空のexeファイルです。 Main関数は、マネージDLLの静的クラスメソッドを呼び出します。 その結果、サイズが5キロバイトのexeファイルを取得します。 OptimizedDLL.dllというマネージアセンブリには、同じ2.25メガバイトのビットマップとフォームがまだあります。 右側の画像をよく見ると、スロット11に青い領域がないことに驚かれるかもしれません! さらに詳しく見ると、2.25メガバイトのアセンブリは他のどこにもありません。



これは非常に健全で、能力を大幅に向上させます。 潜在的に、以前はWindows Phoneでは見られなかった多くのゲームやアプリケーションを開発することが可能になります。 注意、質問。 これはどのように可能ですか? その魔法ですか?





Steven Pratschnerのブログを読んだ人は、Compact Frameworkがマネージドexeとdllをアプリケーションが実行されるスロットの外側の共有メモリの最初のギガバイトに配置することを知っています。これは確かに素晴らしいことです。 しかし、あなたが知らないかもしれないことは、exeファイルがスロットの底で占めるのとまったく同じだけのメモリをオペレーティングシステムが自動的にブロックするということです。 したがって、CLRがアプリケーションの実行を制御し、急いで共有メモリに配置するという事実にもかかわらず、Windows CEはメモリの貴重な部分を選択します。 しかし、アプリケーションは管理可能であり、そこにはありません! 巨大なマネージドexeファイルをお持ちの方は、スロットで大量のメモリを失うことになります。 したがって、最初のレッスンは、ブライアンが行ったことを行うことです。別のマネージアセンブリからアプリケーションを起動するスタブとして空のexeファイルを作成します。





空のexeファイルは次のようになります。

using System;



namespace OptimizedExe

{

static class Program

{

///

/// The main entry point for the application.

///

[MTAThread]

static void Main()

{

OptimizedDLL.StartUp.Main();

}

}

}





* This source code was highlighted with Source Code Highlighter .












アプリケーションを含むライブラリ:

using System;

using System.Windows.Forms;



namespace OptimizedDLL

{

public class StartUp

{

public static void Main()

{

Application.Run( new Main());

}

}

}





* This source code was highlighted with Source Code Highlighter .










そのため、独自のルールに従ってWindows CEを破ることを学びました。 今度は、マネージアセンブリで奇妙な状況について話します。 Reed Robinsonのメモリ内のモンスターの破壊に関するブログを読むと、ライブラリが上のスロットでメモリを食い尽くし、ますます多くのメモリを消費していることがわかるでしょう。 ライブラリとexeファイルの間に空きメモリが残っているため、これを「dllクランチ」(ライブラリグラインド)と呼びます。 しかし、良い知らせがあります。 マネージアセンブリはこのように動作しません! 実際、これらはスロットを占有しないだけでなく、メインアプリケーションスロットにも接触しません。 これはどのように可能ですか?



マネージアセンブリは完全なdllではありません! CLRはそれらを通常のファイルのように扱い、ギガバイトの共有メモリにロードします。 Compact Frameworkの場合、マネージアセンブリは、プロセススロットに分類されないILコマンドで満たされた単なるファイルです。 これで、OptimizedDLL.dllに配置した2.25ビットマップの場所がわかりました。 海外ではスロットの32メガバイトの壁なので、貴重なメモリを無駄にしません!



この新しい方法に従うと、仮想メモリを使い果たす必要がありますか、それとも無料のランチを手に入れることができますか?



昼食は絶対に無料ではありませんが、割引価格で提供されます。 JITコンパイラはスロットで実行され、現在の呼び出しスタックに必要なILコードをロードします。 コンパイルまたは実行する必要のないリソースはアップロードされません。 ガベージコレクター(GCヒープ)のヒープもスロットにあり、選択したオブジェクトはそこにハングします。 スロットには、プロセスを生成する64Kbスレッドスタック(スレッドスタック)が含まれています。 また、アプリケーションドメイン(AppDomainヒープ)の束もあり、アセンブリに記述されている構造のビューが含まれています。







したがって、上記を要約します。





1.空のスタブアプリケーションから呼び出されるマネージアセンブリ内のアプリケーション全体の場所を使用して上記のパターンに従うことにより、未使用のオペレーティングシステムによるメモリの誤った割り当てを最小限に抑えることができます。 5Kbが失われます。 ブライアンありがとう!





2.マネージアセンブリを共有メモリに配置することにより、「ライブラリのガタガタ」による電話上の他のアプリケーションへの害を軽減できます。 また、プロセスのスロットでのメモリ消費も削減されます。




All Articles