フォーラム


ゲスト  

ようこそ ゲスト さん。このフォーラムに投稿するには 登録が必要です。

ページ: [1]
トピック: プログラムで使用可能なメモリの最大値
Mr.XRAY
メンバー
投稿数: 192
プログラムで使用可能なメモリの最大値
on: 2013/06/14 20:47 Fri

使用可能なメモリの量の話です.
32 ビットのコンピュータの場合,Windows も Linux もプロセスが使用するのは,最大 4 GB です.
この内,Windows では 2 GB がカーネルモードとして使われ,残りの 2 GB がユーザモードのアドレス空間として割り当てられます.
1 つのプロセスでは,これ以上のメモリは使用できません.
この 2 GB も,ヒープ領域,スタック領域,クラス関係を格納する領域で使用されます.
また.あるオブジェクトにデータを読み込む際も,実際にはそのオブジェクト内部でもメモリを使用します.
したがって,実際に全てのデータを読み込むという動作で,読み込める量は更に限られてきます.

Windows 7 U64(SP1) + Delphi XE Pro(デフォルトの設定) で,以下のコードで確認してみました.
442 MB のテキストファイル (行数は 7,565,073) は読み込めましたが,
544 MB のテキストファイル (行数は 9,399,932) はメモリ不足で読み込むことができませんでした.
(どちらも 1 行当たり,約 60 バイト相当の行)

procedure TForm1.Button1Click(Sender: TObject);
var
SL : TStringList;
FileName : String;
begin
FileName := '544.txt';
SL := TStringList.Create;
try
SL.LoadFromFile(FileName);
finally
SL.Free;
end;
ShowMessage('END');
end;

end.

 

アプリケーションによっては,大量のデータを読み込んだり,コントロールに表示できるものもあります.
それらは,全てを読み込んでいるわけではなく,表示に必要な量だけ読み込んでいるものと思われます.
データベースでは,時には何億レコードというデータも処理もしなければなりません.そのための仕組みがあるのが普通です.
また,データベースの表示コントロールにも,それなりの機能を持つものもあります.

表示コントロールは,人が目で見るためのものです.一度に大量のデータを読み込んで表示する必要があるのか,
検討する必要もあるのではないか ? と,個人的には思っています.

64 ビットのアプリケーションでは,使用可能なユーザモードのアドレス空間は 8 TB です.

参考リンク
[プロセス アドレス空間]
http://msdn.microsoft.com/ja-jp/library/ms189334.aspx
[仮想アドレス領域 (Windows Drivers)]
http://msdn.microsoft.com/ja-jp/library/hh439648%28v=vs.85%29.aspx
[64 ビット Windows プログラミング ガイド]
http://msdn.microsoft.com/ja-jp/library/bb427430%28v=vs.85%29.aspx

Mr.XRAY
メンバー
投稿数: 192
Re: プログラムで使用可能なメモリの最大値
on: 2013/06/15 06:13 Sat

確認のため,Windows 7 U64(SP1) + Delphi XE2 VCL-64 で 64 ビット版の EXE を作成して実行してみました.
32 ビット版では読み込めなかった 544 MB のテキストも読み込めました.
1.769 GB のテキストファイルも,かなり時間はかかりましたが読み込めました.

なお,メモリ不足で読み込めなかった場合,SysErrorMessage(GetLastError) での表示は,下図のように,
「このコマンドを実行するのに十分な記憶域がありません。」
でした.
 

Mr.XRAY
メンバー
投稿数: 192
Re: プログラムで使用可能なメモリの最大値
on: 2013/06/15 18:24 Sat

TStringList はメモリを消費することでも知られていますが,
空文字ならどうか,次のコードでテストしてみました.
10000 万行と 20000 万行です.
動作確認環境は,同じく Windows 7 U64(SP1) + Delphi XE Pro です.

procedure TForm1.Button1Click(Sender: TObject);
const
ACount = 100000000;
var
ACnt : Integer;
SL : TStringList;
i : Integer;
begin
ACnt := 100000000;
if CheckBox1.Checked then ACnt := ACnt * 2;

SL := TStringList.Create;
try
for i := 0 to ACnt - 1 do begin
SL.Add('');
end;
finally
SL.Free;
end;
Application.MessageBox(PChar(UIntToStr(i)), '結果');
end;

 
10000 万行の結果です.

次は 20000 万行の結果です.「リストの容量が超えました」となりました.
これ以上は追及しないことにします.TStringList を空文字で使用することはあまりないでしょうし,
もし,1 文字でもセットすれば,前のテストのようにメモリ不足になりますから.

Mr.XRAY
メンバー
投稿数: 192
仮想 ListView の Item 数の制限
on: 2013/06/15 19:15 Sat

10000 万行で思い出したのですが,仮想 ListView の行数,Item 数には制限があるようです.
少し前に知ったのですが,Windows API の制限のようです.
どこかコミュニティの場で,どなたかが話題を提供されたのがきっかけだったような記憶があります.
仮想リストビューでない場合は,上の記事のように,これだけの Item を使用したらメモリ不足になってしまうことは確実です.
次のコードでテストしてみました.
動作確認環境は,Windows 7 U64(SP1) + Delphi XE Pro です.

procedure TForm1.FormCreate(Sender: TObject);
begin
ListView1.ViewStyle := vsReport;
ListView1.Columns.Add;
ListView1.Column[0].Width := 150;
//仮想リストビューにする
ListView1.OwnerData := True;
end;

procedure TForm1.Button1Click(Sender: TObject);
const
ACount = 100000000;
begin
ListView1.Items.Count := 0;

if CheckBox1.Checked then begin
ListView1.Items.Count := ACount + 1;
end else begin
ListView1.Items.Count := ACount;
end;
end;

procedure TForm1.ListView1Data(Sender: TObject; Item: TListItem);
begin
Item.Caption := FormatFloat('###,###,##0', Item.Index + 1);;
end;

 
結果の図です.右が 10000 万行を超えた場合です.Item が全く追加されません.

この仮想 ListView では,Item 数が 10000 万までセット可能でした.
TMemo や TRichEdit を使用したテキストエディタ,あるいは TStringGrid 等でも,
同じような仕組みを実装すれば,更に多くのデータの表示はできるということになります.

参考リンク
[Is WinForms ListView in VirtualMode limited to 100,000,000 rows?]
http://stackoverflow.com/questions/2454942/is-winforms-listview-in-virtualmode-limited-to-100-000-000-rows
 
記事修正 2013/06/15 PM 9:02

DEKO
管理者
投稿数: 2631
Re: プログラムで使用可能なメモリの最大値
on: 2013/06/15 22:42 Sat

元ネタはコレですかね?

[仮想リストビューで100000000件を超える値が設定できない (Delphi Q&A)]
http://hpcgi1.nifty.com/MADIA/DelphiBBS/wwwlng.cgi?print+201302/13020015.txt

Mr.XRAY
メンバー
投稿数: 192
Re: プログラムで使用可能なメモリの最大値
on: 2013/06/15 23:09 Sat

引用 DEKO on 2013/06/15 22:42 Sat
元ネタはコレですかね?

 
あっ,これです.これです.
どかだかすぐ思い出させなかったのですが,探すのも面倒なので.
2 月ですか.もっと前だったような気もしていました.

ページ: [1]
WP Forum Server by ForumPress | LucidCrew
バージョン: 1.7.5 ; ページロード: 0.03 sec.