我有一个应用程序,该应用程序从单个对象中的磁盘加载170个文件(假设它们是文本文件),并且一直保持在内存中。从磁盘加载这些文件时,内存一次分配。因此,不涉及记忆分裂。我还使用FastMM来确保我的应用程序永远不会泄漏内存。

该应用程序将所有这些文件彼此比较以找到相似之处。过分简化,我们可以说我们比较文本字符串,但是算法更为复杂,因为我必须在字符串之间允许一些差异。每个文件约为300kb。加载在内存中(持有它的对象),大约需要0.4MB的RAM。因此,运行应用程序大约需要60MB或RAM(工作集)。它处理数据约15分钟。问题是它产生了超过4000万页的故障。

为什么?我有大约2GB的免费RAM。据我所知,页面故障很慢。他们有多少放慢我的计划?如何优化程序以减少这些页面故障?我想这与数据局部性有关。有人知道此(Delphi)的一些示例算法吗?

更新:
但是,查看页面故障的数量(任务管理器中没有其他应用程序接近我的,甚至没有到目前为止),我想如果我设法优化内存布局(减少页面故障),我可以提高应用程序的速度。


Delphi 7,Win 7 32位,RAM 4GB(可见3GB,2GB免费)。

有帮助吗?

解决方案

警告 - 我只解决页面故障问题。

我不确定,但是您是否考虑过使用内存映射的文件?这样,Windows将将文件本身用作分页文件(而不是主页文件pagrefile.sys)。如果仅读取文件,则理论上应减少页面故障的数量,因为页面不需要通过页码文件写入磁盘,因为窗口只会根据需要加载文件本身的数据。

现在,要减少输入和输出文件的文件,您需要尝试沿一个方向浏览数据,以便随着新数据的读取,可以永远丢弃较旧的页面。在这里,您可以再次交易文件并缓存数据 - 缓存必须存储在某个地方。

请注意,内存映射的文件是Windows加载.dlls和.exes等其他内容的方式。我用它们扫描了千兆字节的文件,而没有达到内存限制(当时我们有MB,而不是RAM的GB)。

但是,从您描述的数据中,我建议不返回ovver文件的能力会减少重新振奋的量。

其他提示

在我的计算机上,大多数页面伪造都是针对开发人员工作室报告的,据报道,总CPU时间超过30分钟后具有4M页故障。您将在一半的时间内获得10倍。我的系统上的记忆很少。因此,40m的故障似乎很多。

可能只是 也许 是您的内存泄漏。

工作集 仅是用于应用程序的物理内存。如果您泄漏内存,并且不要触摸它,它将被分类。您将看到虚拟内存USEAGE(或页面文件使用)增加。当堆内存走堆时,这些页面可能会被换回,以再次被Windows交换。

因为您有很多RAM,所以所换的页面将留在物理记忆中,因为没有其他人需要它们。 (从RAM中恢复为软性故障的页面,从磁盘上作为硬磁盘)

您是否使用指数调整大小系统?

如果您在加载时以太小的增量增加了内存的块,则可能会不断请求系统中的大块,然后复制数据,然后释放旧块(假设FastMM(de)直接从OS分配了很大的块)。

也许某种程度上会导致一个循环,其中OS从应用程序的过程中释放内存,然后再次添加它,从而在首次写入时引起页面故障。

还要避免使用TSTSTRINGLIST.LOAD*对于非常大的文件,IIRC消耗了两倍的空间。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top