gpt4 book ai didi

delphi - Delphi XE中占用大量内存的TStringList对象

转载 作者:行者123 更新时间:2023-12-03 14:55:15 25 4
gpt4 key购买 nike

我正在开发一个模拟程序。

程序首先要做的事情之一是读取一个巨大的文件(28 MB,大约 79'000 行),解析每一行(大约 150 个字段),为对象创建一个类,并将其添加到TStringList。

它还会读取另一个文件,该文件在运行期间添加更多对象。最后,大约有 85,000 个对象。

我正在使用Delphi 2007,该程序使用了大量内存,但运行正常。我升级到 Delphi XE,并将程序迁移过来,现在它使用了更多内存,最终在运行中途内存不足。

因此,在 Delphi 2007 中,读取初始文件后最终会使用 1.4 gigs,这显然是一个巨大的数量,但在 XE 中,它最终会使用几乎 1.8 gigs,这确实很大并导致耗尽并得到错误

所以我的问题是

  1. 为什么使用这么多内存?
  2. 为什么 XE 使用的内存比 2007 多得多?
  3. 对此我能做什么?我无法更改文件的大小或长度,并且我确实需要为每一行创建一个对象并将其存储在某处

谢谢

最佳答案

只有一个可以节省内存的想法。

您可以让数据保留在原始文件上,然后只需从内存结构中指向它们。

例如,这就是我们为 browsing big log files almost instantly 所做的事情:我们对日志文件内容进行内存映射,然后快速解析它以在内存中创建有用信息的索引,然后动态地读取内容。读取期间不会创建任何字符串。仅指向每行开头的指针,以及包含所需索引的动态数组。调用 TStringList.LoadFromFile 肯定会慢得多并且消耗内存。

代码是here - 请参阅TSynLogFile 类。诀窍是只读取文件一次,并动态创建所有索引。

例如,以下是我们如何从 UTF-8 文件内容中检索一行文本:

function TMemoryMapText.GetString(aIndex: integer): string;
begin
if (self=nil) or (cardinal(aIndex)>=cardinal(fCount)) then
result := '' else
result := UTF8DecodeToString(fLines[aIndex],GetLineSize(fLines[aIndex],fMapEnd));
end;

我们使用完全相同的技巧 parse JSON content 。使用这种混合方法使用by the fastest XML access libraries .

要处理高级数据并快速查询它们,您可以尝试使用动态记录数组以及我们优化的 TDynArrayTDynArrayHashed 包装器(在同一单位)。记录数组消耗的内存更少,搜索速度更快,因为数据不会碎片化(如果使用有序索引或散列,搜索速度甚至更快),并且您将能够对内容进行高级访问(例如,您可以定义自定义函数来从内存映射文件中检索数据)。动态数组不适合快速删除项目(或者您必须使用查找表) - 但您写道您不会删除太多数据,因此在您的情况下这不会成为问题。

所以你不会再有任何重复的结构,只有RAM中的逻辑和内存映射文件上的数据 - 我在这里添加了一个“s”,因为相同的逻辑可以完美地映射到多个源数据文件(你需要一些“合并”和“实时刷新”AFAIK)。

关于delphi - Delphi XE中占用大量内存的TStringList对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7193590/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com