var a = new double[7000,7000];
FillValue(a,3);
実際には、最初の行を実行した後に.Netはa
にメモリを割り当てません。 FillValue
が実行されている間にのみ、が徐々にのメモリを食べます。 (これは約400MBです)2d配列を初期化するときに.netがメモリを割り当てないのはなぜですか?
誰も私にそれに関する詳細を教えてもらえますか?私はa
がデフォルトの初期化の後で0で満たされていると思った。
var a = new double[7000,7000];
FillValue(a,3);
実際には、最初の行を実行した後に.Netはa
にメモリを割り当てません。 FillValue
が実行されている間にのみ、が徐々にのメモリを食べます。 (これは約400MBです)2d配列を初期化するときに.netがメモリを割り当てないのはなぜですか?
誰も私にそれに関する詳細を教えてもらえますか?私はa
がデフォルトの初期化の後で0で満たされていると思った。
Windowsに「メモリを割り当てる」には、「予約する」と「コミットする」の2つの方法があります。
タスクマネージャは「物理メモリ使用履歴」のみを表示します。 .NET VMは、配列を割り当てるときに予約されたメモリだけを使用し、次に戻って使用される部分をコミットします。
MSDNによれば、実際にメモリを確保せずにメモリを予約することができ、メモリを予約することができます。「実際の物理ストレージをメモリやメモリに割り当てずにプロセスの仮想アドレス空間の範囲を予約します。ディスク上のページングファイル "を参照してください。そういうわけで、タスクマネージャーはそれを表示しません。
詳細については、MSDNのVirtualAlloc
ページを参照してください。
これは実装の詳細なので、それに頼るべきではありません。たとえば、Mono VMは動作が異なる可能性があります。あなたがここに見ることができるよう
私は疎な行列操作で作業するときにそれを利用できると思っています。 – colinfang
は、実際にはメモリを割り当てる:
Console.WriteLine("Memory before: {0}",GC.GetTotalMemory(true));
var a = new double[5000,5000];
Console.WriteLine("Memory after: {0}",GC.GetTotalMemory(true));
Memory before: 118784
Memory after: 200224768
(ideone上
OutOfMemoryException
を防ぐために、配列のサイズを小さくするために必要な)
現在割り当てられていると思われるバイト数を取得します。
FWIWはMonoを使用しています。 –
すばらしい例、thx、今日新しい方法を学んだ:) – colinfang
メモリを割り当てるかどうかをどうやって測定していますか? –
@SethCarnegie悲しいことに、私は非常に粗雑なやり方をしていました... Windowsタスクマネージャーを見て、ブレークポイントを設定して、ループで数回実行します。見つけやすい「塗りつぶし」あたり400MBのメモリです。 – colinfang
これは、オペレーティングシステムの可能性もあります。 「メモリの結合」(http://blogs.msdn.com/b/b8/archive/2011/10/07/reducing-runtime-memory-in-windows-8.aspx –