使用したバージョン: Delphi 7。
仮想 ListView で単純なforループを実行するプログラムに取り組んでいます。データは次のレコードに保存されます。
type TList=record
Item:Integer;
SubItem1:String;
SubItem2:String;
end;
項目は索引です。SubItem1操作のステータス (成功または失敗)。SubItem2ファイルへのパス。forループは各ファイルをロードし、いくつかの操作を行ってから保存します。操作は TStringList で行われます。ファイルはそれぞれ約2MBです。
ここで、メイン フォームで操作を行うと、完全に機能します。
マルチスレッド、巨大なメモリの問題があります。どういうわけか、TStringList は完全に解放されていないようです。3 ~ 4k ファイルの後、EOutofMemory 例外が発生します。ソフトウェアが 500 ~ 600 MB に固執する場合もあれば、そうでない場合もあります。いずれにせよ、TStringList は常に EOutofMemory 例外を返し、ファイルをロードできなくなります。より多くのメモリを搭載したコンピューターでは、例外を取得するのに時間がかかります。
他のコンポーネントでも同じことが起こります。たとえば、 Synapse からTHTTPSendを使用すると、しばらくすると、メモリ消費量が多すぎるため、ソフトウェアは新しいスレッドを作成できなくなります。最大100MBである必要がありますが、約500〜600MBです。メイン フォームでは、すべて正常に動作します。
間違いは私の側にあると思います。多分私はスレッドを十分に理解していません。Destroyイベントですべてを解放しようとしました。FreeAndNil手順を試しました。一度に 1 つのスレッドだけで試しました。スレッドを手動で解放しようとしました(FreeOnTerminateはありません...)
運がない。
これがスレッドコードです。これはあくまでも基本的な考え方です。すべての操作を含む完全なコードではありません。LoadFile プロシージャを削除すると、すべて正常に動作します。スレッドプールに従って、ファイルごとにスレッドが作成されます。
unit OperationsFiles;
interface
uses Classes, SysUtils, Windows;
type
TOperationFile = class(TThread)
private
Position : Integer;
TPath, StatusMessage: String;
FileStringList: TStringList;
procedure UpdateStatus;
procedure LoadFile;
protected
procedure Execute; override;
public
constructor Create(Path: String; LNumber: Integer);
end;
implementation
uses Form1;
procedure TOperationFile.LoadFile;
begin
try
FileStringList.LoadFromFile(TPath);
// Operations...
StatusMessage := 'Success';
except
on E : Exception do StatusMessage := E.ClassName;
end;
end;
constructor TOperationFile.Create(Path : String; LNumber: Integer);
begin
inherited Create(False);
TPath := Path;
Position := LNumber;
FreeOnTerminate := True;
end;
procedure TOperationFile.UpdateStatus;
begin
FileList[Position].SubItem1 := StatusMessage;
Form1.ListView4.UpdateItems(Position,Position);
end;
procedure TOperationFile.Execute;
begin
FileStringList:= TStringList.Create;
LoadFile;
Synchronize(UpdateStatus);
FileStringList.Free;
end;
end.
何が問題なのですか?
ある時点で、作成されるスレッドが多すぎるのではないかと考えました。ユーザーが 100 万個のファイルをロードすると、最終的には 100 万個のスレッドが作成されますが、同時に作成されて実行されるスレッドは50 個だけです。
ご意見ありがとうございます。