こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

C# データ作りすぎでMemoryがフル

現在、以下のデータを大量に作成してMemoryがフルになって困ってます。

List<HogeData> mData = new List <HogeData()>
HogeData hogeData = new HogeData();
for(i =0 ; i < 10000000 ; i++)
mData.Add(hogeData);

そこで、メモリを消費させない方法があれば教えてくれませんか?

今考えてるのは以下です。
1.DataSetなど他のデータクラスに入れる
2.DataSetでXML出力し、一度ファイルなどで保存していく。
  使用するときは出力されたファイルを琢次処理していく。

投稿日時 - 2018-10-12 18:03:13

QNo.9546946

困ってます

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

>また、1EXEは32bitOS0ですとメモリ最大2GB、64bitOSですとメモリ最大4GBしか使用できないWindows仕様がありますよね。
これ、本当でしょうか?
念のため、ググってみましたが、64bitEXEのアドレス空間の上限は4TBのようです。
https://qiita.com/kimuraya/items/1c9023d2bc27ecaed259
少なくとも4GBということはないと思います。

32ビットの4Gの壁を超える仕組みとしてはメモリマップトファイルがありましたが、64bitEXEでは使わずともよいはずです。

物理メモリを超えた部分はスワップファイルが使われます。
スワップファイルの容量は十分でしょうか。
あと、実際にどのくらいのメモリが必要なのかも一度計算しておいたほうがいいと思います。




あと、

>for(........)
><展開>
>}
>
>単一処理
>
>for(........)
><処理>
>}
つまり、展開をすべて完了してからでないと、「単一処理」が行えない、ということでしょうか?
そのあたりの検討をする余地はありそうですが・・・。

検討して、どうしてもとなった場合は、やはりファイルあるいはファイルに準じた処理を行うほうがよさそうです。
ただ、XMLを出力して読み込んでとなると処理時間が非常にかかりそうですのでSqliteあたりを使ってみるのもいいと思います。

投稿日時 - 2018-10-15 21:35:00

お礼

32ビットの4Gの壁=64bitも同様と勘違いしていました。

また、64bitEXEに変更したところ、エラーとなる状況は回避できそうです。

データの扱いに関しては・・できれば全て展開せずにメモリを圧迫させない形で処理したいのですが設計の見直しが必要ですので検討しようと思います。

非常に助かりました、ありがとうございました!

投稿日時 - 2018-10-16 18:07:54

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(5)

ANo.4

#1です。
展開しつつ琢次処理ではだめなのでしょうか?
for(........)
<展開>
<処理>
}
という感じで。

投稿日時 - 2018-10-15 16:43:08

補足

コメント有難うございます。
そこは設計上、下記の流れが必須なもので厳しいです。
for(........)
<展開>
}

単一処理

for(........)
<処理>
}

一度、ファイルに落とし込む作業で何とかできないか調査中です。
(データベース化みたいなイメージです。)

また、1EXEは32bitOS0ですとメモリ最大2GB、64bitOSですとメモリ最大4GBしか使用できないWindows仕様がありますよね。

これを回避するために、何かしら共通メモリ化みたいなプログラムの手法があった気がします。。もしご存知でしたら教えていただけると助かります。

投稿日時 - 2018-10-15 18:05:05

ANo.3

このコードだと、ループの前にhogeDataというインスタンスを一つ作って、リストに追加しているだけですから、大量のデータは作られていないですよね。
実際はリストの要素には、それぞれ別のインスタンスってことだと思うのですが、リストにこれだけのデータを格納する必要があるのか、設計自体を見直すというのは無しですか。10000000個ものインスタンスが常にメモリ上に必要な要件ってのは、なかなか珍しいと思います。
別の視点で、HogeDataクラス自体の容量を減らすことは出来ないのですか。

投稿日時 - 2018-10-12 21:38:10

補足

ご回答ありがとうございます。

設計も見直すのも含めて検討しています。

>10000000個ものインスタンスが常にメモリ上に必要な要件ってのは、な>かなか珍しいと思います。

特殊な処理でして、予め大量データを展開しておかないといけなくそのときにデータをメモリに保存している状況です。(現状8GBがフル)

その後、メモリに保存したデータ配列を逐次処理にて実行する事が目的です。

他の方の補足にも書きましたが、C#プログラムでアプリケーションメモリを増やす方法などありましたら教えていただけると助かります。

投稿日時 - 2018-10-15 11:37:19

ANo.2

メモリーを買い足すって手もありますよ。

投稿日時 - 2018-10-12 19:45:20

ANo.1

純粋に琢次処理でよいのなら、Listなんぞ使わずにただのループで処理すればいいだけですよね。
わざわざListにaddするにはそれなりに理由あってのことと思いますが、どんな理由なのでしょうか?それ次第で最適な方法も違ってくると思います。

投稿日時 - 2018-10-12 18:16:55

補足

ご回答ありがとうございます。

事前に情報を収集しておきたいため、Listなどの配列クラスにデータを蓄積しています。また、データ収集後に逐次処理を実行します。

収集したデータをメモリに蓄積せずに、ファイル化などしていくのも方法化と思っているところです。

投稿日時 - 2018-10-15 11:33:44

あなたにオススメの質問