Home > Mobile >  Are System.Generics.Collections TList<record> subject to memory fragmentation in Delphi?
Are System.Generics.Collections TList<record> subject to memory fragmentation in Delphi?

Time:02-11

In Delphi 10.4, I have a record that I use like this in a TList (System.Generics.Collections):

uses
    System.Generics.Collections;

type
    TSomething = record
        Name: String;
        Foo: String;
        Bar: String;
        Group: String;
        Flag1: Boolean;
        Flag2: Boolean;
        Flag3: Boolean;
        Flag4: Boolean;
        Flag5: Boolean;
    end;

    PTSomething = ^TSomething;


//Simplified code for readability...


var
    Something: TSomething;
    MyList := TList<TSomething>;
    lRecP: PTSomething;

MyList := TList<TSomething>.Create;

while ACondition do
begin
    Something.Name := 'Something';
    //Fill the rest of the record
    MyList.Add(Something); //Add is done in a while loop which result around 1000 items in MyList
end;

//Later...
for i := 0 to MyList.Count - 1 do
begin
    if ACondition then
    begin
        lRecP := @MyList.List[i];
        lRecP.Name := 'Modified'; //Items can be modified but never deleted
    end;
end;

//Later...
MyList.Free;

Is my code prone to memory fragmentation? I have about 1000 records in my list that I will iterate through and maybe modify a string off the record once per record.

Would there be a better way to do what I want to do?

CodePudding user response:

Records lie in intrinsic dynamic array of TSomething. This array will be reallocated when you add new records and expanding is required. Memory manager cares about memory allocation, deallocation, it tries to minimize fragmentation. For list size of 1000 fragmentation should be negligible. Dynamic array capacity changes rarely to avoid expensive operations of reallocation and to diminish fragmentation (more info in SilverWarior comment)

You records contain strings. Strings are really pointers, and strings bodies are in another place of memory. Again - memory manager cares about string allocation/deallocation, it does this work well (applications with instant creation, treatment and deallocation of millions of strings work 24/7 many years).

So frequent changing of strings does not affect on the list body (intrinsic array) (until you add new records/ delete existing ones), and unlikely can cause memory fragmentation.

CodePudding user response:

Not an answer to the question, but a comment-wih-code...

that usage has no benefits from pointer kind of variable

Yes, it has. It provides type compatibility...

Try this:

{$T-}

TYPE
  PInteger = ^Integer;

VAR
  P1 : PInteger;
  P2 : PInteger;
  P3 : ^Integer;
...
  P2:=P1;
  P3:=P1;  // Won't compile in $T- mode

PInteger and ^TInteger are two separate types - they are not assignment compatible (unless you instruct the compiler to relax its validation on pointer types).

See: Type-checked Pointers

  • Related