4000万页面错误。如何解决这个问题?

时间:2010-10-15 11:22:11

标签: delphi page-fault

我有一个应用程序可以从磁盘中加载170个文件(假设它们是文本文件),并且始终保存在内存中。从磁盘加载这些文件时,内存分配一次。因此,不涉及内存碎片。我还使用FastMM来确保我的应用程序永远不会泄漏内存。

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

为什么呢?我有大约2GB的可用内存。据我所知,Page Faults很慢。他们放慢了我的计划多少钱? 如何优化程序以减少这些页面错误?我想这与数据局部性有关。有没有人知道这个算法(Delphi)?

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


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

3 个答案:

答案 0 :(得分:3)

警告 - 我只是解决页面错误问题。

我不能确定您是否考虑使用内存映射文件?这样,windows将使用文件本身作为页面文件(而不是主页面文件pagrefile.sys)。如果文件是只读的那么理论上会减少页面错误的数量,因为页面不需要通过页面文件写入磁盘,因为windows只会根据需要从文件本身加载数据。

现在要减少来自分页的文件,你需要尝试在一个方向上浏览数据,以便在读取新数据时,可以永久丢弃旧页面。这里是您再次浏览文件和缓存数据的地方 - 缓存必须存储在某处。

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

然而,根据您描述的数据,我建议不要返回ovver文件的能力会减少正在进行的重复播放。

答案 1 :(得分:1)

在我的机器上,大多数页面故障都是针对开发人员工作室报告的,据报道,在CPU总时间超过30分钟后,它会出现4M页错误。在一半的时间里,你得到10倍以上。我的系统上的内存很少。所以40M的故障似乎很多。

它可能可能你有内存泄漏。

working set只是您的应用程序使用的物理内存。如果您泄漏了内存,并且没有触摸它,它将被分页。您将看到虚拟内存使用(或页面文件使用)增加。当堆内存遍历堆时,这些页面可能会被交换回来,以便被Windows再次换出。

因为你有很多RAM,所以换出的页面将保留在物理内存中,因为没有其他人需要它们。 (从RAM恢复的页面计为软故障,从磁盘作为硬故障)

答案 2 :(得分:0)

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

如果在加载时以非常小的增量增加内存块,它可能会不断地从系统请求大块,复制数据,然后释放旧块(假设fastmm(de)直接分配非常大的块来自OS)。

也许这会导致一个循环,操作系统从你的应用程序的进程释放内存,然后再次添加它,导致第一次写入时出现页面错误。

对于非常大的文件,也避免使用Tstringlist.load *方法,IIRC会消耗两倍所需的空间。