言語はC#、開発環境はVisualStudio2008、OSはwindows7です。
また、メモリは4GBです。
HashSetに次々に整数を格納していくテストコードを作成したのですが、
メモリにはまだ余裕があるにも関わらず、
5000万個程度の整数を格納するとexeが落ちます。
これはどういう事情なのかを教えてください。
例えば、exeファイルにサイズ制限があるのか、
HashSetに上限があるのか、
HashSetは連続したメモリ領域を確保しないといけない、とか
そのような事情があるのでしょうか?
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万バイト」という計算にはならないので注意してください。
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数との関係を確認する等して下さい。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- 労働相談 合意済み仕様の商品納入後における仕様変更要求への対応について 5 2023/04/19 09:41
- C言語・C++・C# sprintf()の使い方について 1 2022/08/17 16:16
- Visual Basic(VBA) batからexeを実行し戻り値を受け取る EXEの実行内容の結果によって、戻り値を0か1かで返したい 1 2023/07/04 16:40
- ノートパソコン あなたのパソコン(Windows限定)は何年使っていますか? 4 2023/05/27 08:04
- Visual Basic(VBA) VBA★PDFをPDFアプリで印刷しようと思っていますが上手くゆきません 1 2022/06/06 22:04
- その他(プログラミング・Web制作) pythonでクラスで複数のメソッドを利用する方法 2 2022/04/15 04:17
- ビデオカード・サウンドカード PC版:スーパーロボット大戦30 推奨環境を満たしておりますが、動作(処理)が遅いかもしれません。 1 2023/01/26 13:45
- その他(セキュリティ) 役所など、情報系システムのセキュリティが弱くても業務システムに問題ないか 3 2022/11/02 16:38
- Visual Basic(VBA) batからexeを実行し戻り値を受け取る バッチからEXEの結果を受け取りたいのですが、 下記のバッ 1 2023/07/04 15:13
- Windows 10 explorerをedgeで開く方法 2 2022/06/05 14:59
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C言語で、メモリを解放しないで...
-
VBAの配列サイズとメモリに関して
-
C言語における再帰呼び出しの...
-
「ヒープサイズの設定」て何?
-
EXCEL-VBAにてADOのレコードセ...
-
「memcpy」と「strcpy」について
-
変数をあなたの身近なものに例...
-
エクセルVBA 大容量CSVファイル...
-
Linuxでexit()をフックするには?
-
FindFirstFile ハンドル開放
-
C#のOutOfMemoryException発生...
-
LoadLibraryしたらFreeLibrary
-
closeとメモリの開放について
-
matlabのメモリ制限 と inte...
-
移動可能メモリ
-
C言語初心者です。debug assert...
-
C++でメモリの絶対番地を指定...
-
バッチファイルでの実行EXEのメ...
-
メモリのセグメント違反の解決...
-
GPUプログラミング時の表示用GPU
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
C言語で、メモリを解放しないで...
-
VBAの配列サイズとメモリに関して
-
「ヒープサイズの設定」て何?
-
エクセルのメモリ使用状況/Appl...
-
エクセルVBA 大容量CSVファイル...
-
EXCEL-VBAにてADOのレコードセ...
-
バッチファイルでの実行EXEのメ...
-
メモリ不足
-
メモリのセグメント違反の解決...
-
メモリが不足しています(VBA)
-
【C言語】再帰が時間がかかる...
-
ファイルマッピング関数で失敗
-
C言語:関数のメモリ上でのサイ...
-
メモリの解放の仕方
-
VC++におけるメモリ使用量について
-
メモリの消費量について
-
Bitmapを重ね合わせる方法
-
メモリを解放しないとどうなる?
-
C#のOutOfMemoryException発生...
-
メモリの解放について VB6 VBA
おすすめ情報