喫茶XRAYトップページ

[スレッド全体
]

[13435] 配列のメモリ確保返信 削除
2022/8/3 (水) 18:02:03 Mr.XRAY
[ 動的配列でメモリー不足の回避 ]
https://www.petitmonte.com/bbs/answers?question_id=29968

某掲示板で上のような書き込みがありました.
で,やってみました.
すご〜く時間がかかります.経験しておくといいと思います (笑)


unit Unit1;

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
  Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls;

type
  PRData = ^RData;
  RData = Record
    denc : Word;
    od : Single;
    norm1 : Single;
    disp1 : Byte;
    lvl1 : Word;
    dose : Single;
    norm2 : Single;
    disp2 : Byte;
    lvl2 : Word;
  end;

  RMTX  = Record
    ARY : Array [ 1 .. 6 ] of RData;
  end;

  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
    function UsesMemory: UInt64;
  end;

var
  Form1: TForm1;

type
  ARY = Array of Array of Array of RMTX;

implementation

{$R *.dfm}

uses
  psAPI;

//=============================================================================
//  多次元配列のメモリ確保状況確認テスト
//  事実上 4 次元の配列
//  非常に時間がかかる
//
//  [動作確認]
//  Windows 10 ビルド 19043 + Delphi XE5(UP2) Pro VCL-64
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
  LSize    : Integer;
  LAry1 : ARY;
  LAry2 : ARY;
  LAry3 : ARY;
begin
  LSize := 512;
  SetLength(LAry1, LSize, LSize, LSize);
  SetLength(LAry2, LSize, LSize, LSize);
  SetLength(LAry3, LSize, LSize, LSize);

  Memo1.Lines.Add(FormatFloat('###,##0 KB', UsesMemory div 1024));
  Memo1.Lines.Add('End');
end;

//=============================================================================
//  自プロセスのメモリ使用量
//=============================================================================
function TForm1.UsesMemory: UInt64;
var
  LSize       : Cardinal;
  LProcessMem : PPROCESS_MEMORY_COUNTERS;
  LMemUsed    : Cardinal;
begin
  LSize := SizeOf(_PROCESS_MEMORY_COUNTERS);
  GetMem(LProcessMem, LSize);
  try
    LProcessMem^.cb := LSize;
    // GetCurrentProcessを他のプロセスのハンドルにすれば,そのプロセスのメモリ
    // 使用量が取得できる
    if GetProcessMemoryInfo(GetCurrentProcess, LProcessMem, LSize) then begin
      LMemUsed := LProcessMem^.WorkingSetSize;
    end else begin
      LMemUsed := 0;
    end;

    Result := LMemUsed;
  finally
    FreeMem(LProcessMem);
  end;
end;

end.



[13436] Re:配列のメモリ確保返信 削除
2022/8/3 (水) 18:03:11 Mr.XRAY
下図はシステムのメモリの使用量です.

1 番目は,上のサンプルの EXE 起動直後
2 番目は,メモリ確保中で,Button1 クリックのイベント実行中の時
     ものすごいメモリを使用しています.ハハハッ.
     32 GB もありますが,パンクしそうです.
3 番目は,メモリ確保終了後です.Button1 クリックイベント終了時



[13437] Re2:配列のメモリ確保返信 削除
2022/8/3 (水) 18:19:50 Mr.XRAY
>      32 GB もありますが,パンクしそうです.

64 bit のプロセスの場合,ユーザが使用可能なメモリは 8 GB です.
しかし,今回のように,一度に大量の処理をすると,
その前に,システム全体としてのメモリが不足してしまうかもです.

ご愁傷様でございます.
良い子の皆さんは気を付けてくださいね.


[13439] Re3:配列のメモリ確保返信 削除
2022/8/4 (木) 10:00:42 Mr.XRAY
> しかし,今回のように,一度に大量の処理をすると,
> その前に,システム全体としてのメモリが不足してしまうかもです.


TStingList 等,文字列の処理にも結構,作業用にメモリを使用します.


[▼次のスレッド]
INCM/CMT
Cyclamen v3.82