Note that there are some explanatory texts on larger screens.

plurals
  1. POTStringList and TThread that does not free all of its memory
    primarykey
    data
    text
    <p><strong>Version used:</strong> Delphi 7.</p> <p>I'm working on a program that does a simple <em>for</em> loop on a Virtual ListView. The data is stored in the following record:</p> <pre><code>type TList=record Item:Integer; SubItem1:String; SubItem2:String; end; </code></pre> <p><em>Item</em> is the index. <em>SubItem1</em> the status of the operations (success or not). <em>SubItem2</em> the path to the file. The <em>for</em> loop loads each file, does a few operations and then, save it. The operations take place in a TStringList. Files are about 2mb each.</p> <p>Now, if I do the operations on the main form, it works perfectly.</p> <p>Multi-threaded, there is a huge memory problem. Somehow, the TStringList doesn't seem to be freed completely. After 3-4k files, I get an EOutofMemory exception. Sometimes, the software is stuck to 500-600mb, sometimes not. In any case, the TStringList always return an EOutofMemory exception and no file can be loaded anymore. On computers with more memory, it takes longer to get the exception.</p> <p>The same thing happens with other components. For instance, if I use <em>THTTPSend</em> from Synapse, well, after a while, the software cannot create any new threads because the memory consumption is too high. It's around 500-600mb while it should be, max, 100mb. On the main form, everything works fine.</p> <p>I guess the mistake is on my side. Maybe I don't understand threads enough. I tried to free everything on the <em>Destroy</em> event. I tried <em>FreeAndNil</em> procedure. I tried with only one thread at a time. I tried freeing the thread manually (no <em>FreeOnTerminate</em>...)</p> <p>No luck.</p> <p>So here is the thread code. It's only the basic idea; not the full code with all the operations. If I remove the <em>LoadFile</em> prodecure, everything works good. A thread is created for each file, according to a thread pool.</p> <pre><code>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. </code></pre> <p>What could be the problem?</p> <p>I thought at one point that, maybe, too many threads are created. If a user loads 1 million files, well, ultimately, 1 million threads is going to be created -- although, only 50 threads <strong>are created and running at the same time</strong>.</p> <p>Thanks for your input.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload