简体   繁体   English

是System.Generics.Collections TList<record> 受 Delphi 中 memory 碎片的影响?</record>

[英]Are System.Generics.Collections TList<record> subject to memory fragmentation in Delphi?

In Delphi 10.4, I have a record that I use like this in a TList ( System.Generics.Collections ):在 Delphi 10.4 中,我有一条在TList ( System.Generics.Collections ) 中使用的record

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?我的代码容易出现 memory 碎片吗? I have about 1000 records in my list that I will iterate through and maybe modify a string off the record once per record.我的列表中有大约 1000 条记录,我将遍历这些记录,并且可能每条记录修改一次记录外的字符串。

Would there be a better way to do what I want to do?会有更好的方法来做我想做的事吗?

Records lie in intrinsic dynamic array of TSomething.记录位于 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. Memory 管理器关心 memory 的分配、释放,它尽量减少碎片。 For list size of 1000 fragmentation should be negligible.对于 1000 的列表大小,碎片应该可以忽略不计。 Dynamic array capacity changes rarely to avoid expensive operations of reallocation and to diminish fragmentation (more info in SilverWarior comment)动态数组容量很少改变以避免重新分配的昂贵操作并减少碎片(更多信息在 SilverWarior 评论中)

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).字符串实际上是指针,字符串主体在 memory 的另一个地方。再次 - memory 管理器关心字符串分配/解除分配,它做得很好(即时创建、处理和解除分配数百万个字符串的应用程序多年来 24/7 工作).

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.如此频繁地更改字符串不会影响列表主体(内部数组)(直到您添加新记录/删除现有记录),并且不太可能导致 memory 碎片。

This is not an Answer to your Code.这不是您的代码的答案。 I don´t know if Fragmentation happens.我不知道是否会发生碎片化。 In my experience it is dependent on other things happening in parallel or over time.根据我的经验,它取决于同时发生或随时间发生的其他事情。 If your Application has Issues like "E Out Of Memory" after running several days, then its time to look at it.如果您的应用程序在运行几天后出现“E Out Of Memory”之类的问题,那么是时候查看它了。

I Would suggest having a look at FastMM.我建议看看 FastMM。 Using its FastMMUsageTracker Memory Fragmentation Map over FastMM 在 FastMM 上使用其 FastMMUsageTracker Memory 碎片 Map

For me it was a big help.对我来说这是一个很大的帮助。 I had Problems in a Service, but i cant remember where i read about Memory Exhaustion.我在服务中遇到问题,但我不记得我在哪里读到有关 Memory 耗尽的信息。 In FastMM or Mad Except?在 FastMM 或 Mad Except 中? Sorry i can´t remember.对不起,我不记得了。 It was a Article explaining why Fragmention happens over time.这是一篇文章,解释了为什么碎片会随着时间的推移而发生。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM