2012-01-27 14 views
3

私は、C#がページファイルにオブジェクトを書き込むことが可能かどうか疑問に思っていました。でも、64ビット版のWindows上で -C#はオブジェクトをページファイルに書き込むことができますか?

は、私はすでに.NETアプリケーションの仮想マシンのみが2 GBのRAMを使用し、そのずっと前にメモリ不足になると一つのオブジェクトを許可するように制限されていることを知っています。

しかし、膨大な量の文字列を読み込むことができるようにする必要があります(大きなものではなく、小さなものもたくさんあります)。読み込みが可能かどうか不思議に思って、必要になるまでスワップ空間に書き込めますもう一度(残念ながら、私が作業しているコードを呼び出すアプリケーションによって強制されるため、すべての文字列のロードを防ぐことはできません)。

public static void Main() 
{ 
     ICollection<StringBuilder> builders = new LinkedList<StringBuilder>(); 
     double used_ram = 2*1024*1024*1024L; 
     int blocksize = 12800000; 
     int blocks = (int) (used_ram/blocksize); 
     for (int i = 1; i < blocks ; i++) 
     { 
      StringBuilder sb = new StringBuilder(blocksize/2); 
      builders.Add(sb); 
     } 
     Console.ReadLine(); 
} 

私がいた:私はそれが一つの巨大な文字列を割り当てようとしませんが、(それがする)次のプログラムは、同様にメモリ不足になるかどうかを確認するために試してみたそれをプロトタイプに

文字列がスワップ空間に書き込まれることを期待し、アプリケーションに強制的にそれをさせることができる方法があるかどうか疑問に思っていました。

EDIT:スワップファイルの使用をページファイルに変更しました(説明のためにありがとう)。

私の質問を強化するために:ランタイムの唯一の制限は、1GBのメモリが2GB以上のメモリを割り当てることができない場合です。なぜ、上記のコードがメモリ不足になるのですか?リストは2GBすべての文字列ビルダーへの参照を保持することによってメモリの?

+9

"スワップへの書き込み"は、アプリケーションが行うことではなく、OSがアプリケーションに対して行うことです。あなたのアプリケーション/環境が2Gアドレス空間に制限されている場合、 "スワップ"の量はそれを増加させません。 – Mat

+0

残念ながらそれは私が期待したことです - 私は本当にこれらの概念すべてを実際に把握するためには、メモリ管理の基礎を調べなければならないと思います。したがって、ランタイムによって割り当てられるスペースを増やす方法はありませんか?それから私はおそらく、文字列をファイルや必要なものが格納されるまで書き込む必要があります。 – BergmannF

+0

スワッピングは70年代にスタイルから外れました。現在、仮想メモリシステムは「ページング」を行っています。 Windowsでは、仮想メモリは「ページファイル」にページされます。 – Gabe

答えて

2

短い回答:できません。スワップを使用して

は、アプリケーションが行うものではありません:オペレーティングシステムのメモリ管理システムは、その責任があります。

あなたは1時間にあなたのプロセスにおけるデータの2GB以上をロード(および必要に応じてチャンクごとのディスクからデータを取得できません)する必要がある場合は、深刻な設計上の問題を抱えています。


EDIT: すでに64ビットのOSを使用しているとして、あなたがx64プラットフォーム(またはAnyCPU)用にアプリケーションをコンパイルしていると、アプリケーションが32ビットとして実行されていないことを確認してくださいプロセスはWOW64を使用します。

+0

の制御権を持っています。私は本当にそれが書いているアプリケーションに依存していると言います。多くの場合、設計上の問題となることがありますが、大量のデータをメモリにロードすることが実際に必要になることがあります。 – Kibbee

+0

私はチームの新入生であり、まだシステムで握手しようとしているので、実際にはシステムの設計について議論することはできませんが、これは私が調べるべき最初の問題の1つでした。再設計は私の認証レベルから少し外れています。 – BergmannF

+0

@Kibbee私は、いくつかのアプリケーションで実際に2GB以上のデータをロードする必要があることに同意します。しかし、OPのこの特定の場合(多くの小さな弦)、私は本当にそれが悪いデザインだと思う。 – ken2k

1

は、Windowsのメモリ管理機能のすべてを活用し、できるだけ多くのメモリを割り当てるシステムができるようになりますように、しかし、あなたはディスクシステムへのフラッシュのいくつかのタイプに悲鳴をやっていることができます。あなたがその大きなオブジェクトを割り当てるウィンドウを得ることができたとしても、パフォーマンスはひどいでしょう。大量のデータを格納し、非常に短い順序でアクセスできるボックスシステム(データベースと呼ばれる)が数多くあります。

+0

はい、それは私がすでに考えていたものでした - 私は自分自身で割り当てたすべてのオブジェクトがオブジェクトあたり2GBという制限の下でうまくいけば、システムがメモリ不足になるのを疑問に思っています。小規模な例もあります - 私は質問で十分明確ではないと思います - ごめんなさい)。 – BergmannF

+0

OSのメモリを管理する方法が不足しているため、このファイルは不足しています。最適な条件のもとでも、2GBは非常に大きなメモリであり、あなたが何をしていてもページングされます。そのプロセスだけではなく、あなたは – rerun

2

私はあなたの質問の量はに思う:32ビットの.NETアプリケーションがメモリの2GB以上に対応することができ

はい、ユーザーアプリケーションに割り当てられたメモリとオペレーティングシステムとの間の分割を調整することで、アプリケーションが対処できるメモリの量を増やすことは可能ですが、ほとんどの場合、ネットワーキングなどのO/S機能にはそれほど微妙な問題はありません。/3GBおよび/USERVAスイッチの詳細については、this articleを参照してください。これにより、アプリケーションは2GBではなく3GB(オーバーヘッドからオーバーヘッド)のメモリを扱うことができます。あなたの処分で

ツールは、以下のとおりです。64ビットの.NETへの切り替え

  • メモリマップファイルの使用。
  • 独自のページングシステムを作成しています。
  • いくつかのバッキングストアを使用しています。ファイルシステム、データベース
0

独自のキャッシュクラスを作成することをおすすめします。例を見てくださいhere

1

あなたは何か間違っている可能性があります。 2GB以上のメモリを使用する.netアプリケーションを作成しました。 64ビットのウィンドウを実行している場合、アプリケーションがより多くのメモリを使用できないようにする必要はありません。

+0

これで、リストにはすべての文字列ビルダーへの参照が保持されるため、小さなサンプルのメモリが不足していると思いますか? – BergmannF

+0

私はそれが問題だとは思わない。私の計算では約167ブロックしかありません。あなたのリンクされたリストに多くのエントリを格納することはあまりにも多くの問題を作り出すべきではありません。文字列ビルダーのコピーは格納されず、参照のみが格納されます。プロファイラが利用可能な場合は、それを使用してすべてのメモリがどこにあるのかを確認する必要があります。 – Kibbee

0

私は、.NETアプリケーションレベルであなたのアプローチに近いものはMemoryMappedFileであると思います。

しかし、これはアプリケーションがすべての文字列を一度に取得しようとしないことを意味します。