Версия используется: Delphi 7.TStringList и TThread, что не освобождает все его памяти
Я работаю над программой, которая делает простой для петли на виртуальном ListView. Данные хранятся в следующей записи:
type TList=record
Item:Integer;
SubItem1:String;
SubItem2:String;
end;
Пункт является индексом. SubItem1 статус операций (успех или нет). SubItem2 путь к файлу. Цикл для загружает каждый файл, выполняет несколько операций и затем сохраняет его. Операции выполняются в TStringList. Файлы размером около 2 мб каждый.
Теперь, если я выполняю операции на основной форме, он отлично работает.
Многопоточная проблема с огромной памятью. Так или иначе, TStringList, похоже, не полностью освобождается. После файлов 3-4k я получаю исключение EOutofMemory. Иногда программное обеспечение задерживается до 500-600 мб, иногда нет. В любом случае TStringList всегда возвращает исключение EOutofMemory, и файл больше не может быть загружен. На компьютерах с большей памятью требуется больше времени для получения исключения.
То же самое происходит с другими компонентами. Например, если я использую THTTPSend от Synapse, через некоторое время программное обеспечение не сможет создавать новые потоки, потому что потребление памяти слишком велико. Это около 500-600 мб, в то время как это должно быть, max, 100 МБ. На основной форме все работает нормально.
Я предполагаю, что ошибка на моей стороне. Возможно, я недостаточно разбираюсь в потоках. Я попытался освободить все на турнире Destroy. Я пробовал FreeAndNil процедура. Я пробовал только один поток за раз. Я попытался освободить нить вручную (нет FreeOnTerminate ...)
Не повезло.
Итак, вот код темы. Это только основная идея; а не полный код со всеми операциями. Если я удалю LoadFile prodecure, все будет хорошо. Поток создается для каждого файла в соответствии с пулом потоков.
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.
В чем проблема?
В какой-то момент я подумал, что, может быть, создано слишком много потоков. Если пользователь загружает 1 миллион файлов, ну, в конечном счете, будет создано 1 миллион потоков - хотя одновременно создаются и работают только 50 потоков .
Спасибо за ваш вклад.
@TLama Уже сделал это ... и в соответствии с FastMM, нет утечки памяти, за исключением тех из Delphi 7. – VanillaH
@TLama 13 - 20 байт: AnsiString х 1 29 - 36 байт: Unknown х 1 45 - 52 bytes: TStringList x 2 Я считаю, что это утечки памяти из самого Delphi. Поправьте меня если я ошибаюсь. – VanillaH
У меня никогда не было утечек памяти из Delphi. –