• ベストアンサー

C#におけるexeファイルのサイズ制限?

言語はC#、開発環境はVisualStudio2008、OSはwindows7です。 また、メモリは4GBです。 HashSetに次々に整数を格納していくテストコードを作成したのですが、 メモリにはまだ余裕があるにも関わらず、 5000万個程度の整数を格納するとexeが落ちます。 これはどういう事情なのかを教えてください。 例えば、exeファイルにサイズ制限があるのか、 HashSetに上限があるのか、 HashSetは連続したメモリ領域を確保しないといけない、とか そのような事情があるのでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
  • wormhole
  • ベストアンサー率28% (1622/5658)
回答No.2

何か例外がスローされてると思いますが、それは確認されましたか? VisualStudio 2013でですが私の方で試してみましたけど using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { HashSet<int> a = new HashSet<int>(); for (int i = 0; i < 50000000; i++) { try { a.Add(i); } catch (Exception e) { Console.WriteLine("i={0}", i); Console.WriteLine("{0}", e); break; } } } } } を32ビットモードで実行すると i=23997907 System.OutOfMemoryException: 種類 'System.OutOfMemoryException' の例外がスローされました。 場所 System.Collections.Generic.HashSet`1.SetCapacity(Int32 newSize, Boolean forceNewHashCodes) 場所 System.Collections.Generic.HashSet`1.IncreaseCapacity() 場所 System.Collections.Generic.HashSet`1.AddIfNotPresent(T value) 場所 System.Collections.Generic.HashSet`1.Add(T item) 場所 ConsoleApplication1.Program.Main(String[] args) 場所 c:\~\Program.cs:行 18 で例外がスローされているのが確認できました(例外の意味までは説明しません)。 64ビットモードで実行する分には正常に終わります。 >メモリにはまだ余裕があるにも関わらず、 これはどこで確認されましたか? Windowsのタスクマネージャーなどでしたら空きがあるように思えても32ビットアプリケーションは通常2GBまでしか使用できません。 また#1の方も説明されていますがHashSetが要素を管理する分のメモリもありますし、C#ではintもSystem.Int32構造体の別名なので4バイトというわけではなく、単純に「メモリ使用量4*5000万バイト」という計算にはならないので注意してください。

ibm_111
質問者

お礼

ありがとうございます。 64ビットwindows8、64ビットモードでコンパイルしたところ、 実行できるようになりました。

その他の回答 (1)

  • ninoue
  • ベストアンサー率52% (1288/2437)
回答No.1

C#は使った事はないので類推ですが、やはりOS或いはC#プログラムのサイズリミットに掛かっているのではないかと思われます。 先ずプログラムリンク時に(デフォルトで?)指定されるプログラムサイズリミット値、或は実行時のサイズ制限値等を確認下さい。 HashSetではObject対応でhash value:hvが計算され、例えばHash_Table_Base+hv*4でindex引きして同一hvを持ったObjectのchainを辿って指定されたObjectがないかスキャンしたりします。 このHash_Tableは連続番地に割り当てる必要があります。 integer object一個毎にinteger valueとして4byte, object headerに4-8byte, 同一hash value chainに4byte, Hash_Tableのentry数の割合は全object数の例えば1/4 - 1 (1.25)倍程度, 1enty当りpointer一個4byte程度は必要でしょう。 従って 1 Integer Object当り12-16byte, 連続割り当てのHash_Table Areaとして Object数*(1-4)バイト程度は必要となります。 なお、Hash_Table Areaはentry数が多くなるのに従って、最初は100entry, 1000, 10000entry等と再構成されて行きます。 50M entry * 20 = 1GB程度、その内200MBは連続番地等が必要となる可能性があると思われます。 タスクマネージャでテストプログラムのメモリ使用量とentry数との関係を確認する等して下さい。

ibm_111
質問者

お礼

ありがとうございます。 64ビットモードでコンパイルしたところ、 実行できるようになりました。

関連するQ&A

  • 【VC2008】実行ファイル(exe)に引数を渡すやり方

    タイトルの実行ファイル(仮にtest.exe)は、バッチファイルにします。 ------------------------------------------------ @echo off test.exe 引数1(文字列) 引数2(整数) ・・・ ------------------------------------------------ やりたい事は、上記の引数の testプロジェクト内での受け取り方です。 開発環境は、VC2008 の CLRコンソールアプリケーションです。 どなたかやり方をご存知の方がいらっしゃいましたら、ご教授の程よろしくお願いいたします。

  • c言語のmalloc関数、またrealloc関数

    c言語のmalloc関数は確保するメモリの領域を、配列としてのみしか処理出来ないのですか。 つまり、malloc関数で確保したメモリの領域を変数、また多次元配列、また構造体としては処理出来ないのでしょうか。 c言語のrealloc関数は以前の確保したメモリの領域から、確保し直したメモリの領域の場所が変わるかもしれないという事ですが、この場合の場所が変わるという意味は、メモリの領域のアドレスが変わるという事でしょうか。 また、以前の確保したメモリの領域に代入していたデータが使用出来なくなるという事でしょうか。

  • COM(EXE)を用いたプロセス間のポインタ

    複数のプロセスの間にEXEタイプのCOMを用意し、Clientであるプロセスにおいて、new等を用いてヒープ領域のメモリを確保します。 COMに対して確保した領域のポインタを渡し、COMの内部でそのポインタを保持させ、他のプロセスがそのポインタを取得し、他方のClientプロセスが作成したデータを参照するといったことは可能なのでしょうか? 開発環境は、WinXP、VC++6.0です。 ご教授お願いします。

  • c言語のメモリの確保について

    c言語で変数を宣言したり、領域を確保したりする場合に、メモリ上のこのアドレスに領域を確保する、といったように場所を指定することはできるのでしょうか?

  • マイコンのRAMサイズについて

    マイコン初心者です。 あるプログラムをマイコンへ組み込んでいます。 使用しているのはSTM32F030R8です。 RAMサイズは8KBとのことですが、メモリを確保できる領域の 上限がわからなくて困っています。 アプリで利用できる領域の上限はどれくらいでしょうか? 結果だけでなく、調べ方を合わせてご教示いただけると幸いです。 よろしくお願い致します。

  • DLL内部異常発生時、EXEをまきこまれない

     現在、Windows上で動作する、とあるEXEを開発しています。 <EXE実行環境> OS:Window7 32bit <EXE開発環境> MS VC++2008 ※言語は、C++/CLI <DLL開発環境> MS VC++2008 ※言語は、C++ 私自身が携わっているEXEから、必要に応じて、外部委託したDLLを呼出すことを行っています。 現状、結合テストを行っている最中なのですが、この「DLL」がひどいできで、頻繁に異常終了します。 DLL異常終了で、EXEが巻き込まれてしまう為、テスト者に頻繁に呼出されてしまうのを避けたいのです。(このDLLの開発チームというか、開発者が、そもそもテストしたのかどうか疑っているレベルです) 例えば、EXE側で例外トラップ等をしてやることで、DLL内部で発生した異常を完全に捕らえることは可能でしょうか。 また、別途良い方法はないでしょうか。

  • 入力待ち状態になるexeファイルの、C言語プログラムからの操作

    ただ今開発しているプログラムの中で使用しようと思っているソフトウェアがあるのですが、 exeファイルを実行するとcmd上で入力待ち状態になってしまいます。 この入力待ち状態の時に、なんとかC言語プログラムから入力内容を指定したいと思っているのですが、 良い方法をご存知の方はいないでしょうか? しかもこのソフトウェア、入力して処理が終了したあとも入力待ち状態になり、 それが繰り返されてしまうせいで、ログをとりたいのですがコマンドを指定することが出来ません。 開発環境はVisualStudio2005 VC++です。 抽象的な説明になってしまい申し訳ありません。 説明不足な点が多いと思うので、指摘してください。 どなたか解決方法をご存知の方がいましたら、お願いします。

  • C言語におけるローカル変数が使用するメモリについて

    例のようなC言語のプログラムを動かした場合、 確保されるメモリ領域はどうなるのでしょうか。 例 #include <stdio.h> int main(void) { int a = 0; } このとき、変数aはint型なのでスタック領域に4バイトのメモリが確保されると理解しています。 と同時にaという変数名と確保されたスタック領域の番地を紐づけるようなメモリがどこかに確保されるのではないかと思ってるのですが、この理解で正しいでしょうか。 またその場合は変数aの番地はどの領域に確保されるのでしょうか。 ご教示お願いいたします。

  • exeファイルが何もせず終了してしまいます。

    exeファイルが何もせず終了してしまいます。 exeを起動することによりDOSが起動し、ユーザ入力を求めるプログラムを 作成し、exeを作成しました。 私のPCで実行したところ正常に処理が開始(DOS画面が起動)されますが、 新しく導入したPCにexeファイルを移植したところ処理が開始されず 終了してしまいます。 (一瞬DOSが立ち上がるのですが、すぐに終了してしまう。) 他のexeを試したところ、ファイルサイズの小さい(200KB)程度の exeは正常に動作しますが、該当のexe(500KB)のexeのみ実行 出来ないようです。 新しいPCの設定周りがおかしいのかな?と思い以下の 対応をしましたが、改善されません。 http://pasofaq.jp/windows/startmenu/exefile.htm 私のPC、新しいPCともにOSはWindowsXP、開発言語はCです。 プログラムの詳細は諸事情により記述できません。。 情報が少なく申し訳ありませんが、 類似した事例を経験された方がいらっしゃいましたら対処法を 教えて頂ければと思います。

  • 行数の変動にも対応したファイル読み込みのやり方

    学校でファイル読み込みの課題を今しているのですが、ファイルの行数が増えた場合にも対応していて、且つ無駄な領域を使わないようなファイル読み込みをするのに困っています。 流れとしては csvファイルから内容を読み込む ↓ カンマで分割し、構造体に格納 ↓ その格納した構造体を返す という動きをしたいのですが、構造体をmallocで動的にメモリ確保する時にも、行数の取得が必要になってきて・・・ 一度行数を調べてから、処理を行う方法を取るか、他のchar型配列か何かに一度全てを格納して、そのときにカウントした行数を使って構造体のメモリを動的に確保する・・・くらいまでは思いついたのですが、始め全てを格納する時点でもまた動的にメモリを格納する方法が思いつかなくて・・・・ やはりどこかで多めに領域を取り、そこに格納する手を使うしかないのでしょうか? ご教授お願いします。