没有页面文件的Windows XP内存管理-关于堆碎片化有什么后果?

10

我一直在研究一个在Windows XP嵌入式系统上的应用程序中出现的难以捉摸的错误。

我们已经将问题缩小到了一个指针,该指针应该指向一块内存,但却指向了NULL。由于使用malloc(..)调用分配内存时未进行检查,我的直觉告诉我malloc失败并返回了NULL(尽管我们现在也在寻找其他可能性,例如无意间更改指针的竞争条件)。这是一个本地的C++应用程序。跟踪崩溃原因有点复杂,主要因为我们只有事后崩溃转储,并且故障表现在我们没有源代码的第三方库中,位于不同的线程中。开心的时光 :)

我的问题集中在内存耗尽的可能性。重要的是,我们运行的XP嵌入式系统已经禁用了页面文件。

所以,我有三个问题;如果有人能为我澄清这些问题,那就太好了:

  • 首先,没有页面文件会有什么影响?这是否意味着当堆增长时,操作系统需要立即找到并分配新内存,即使那些空闲块不会立即使用?我看到一些轶闻提到了它,但找不到有关禁用页面文件具体影响的任何信息。

  • 为什么Microsoft决定直到Windows Vista才默认启用低碎片堆(LFH)?在Windows XP上为进程启用LFH是否存在危险?

  • WinDbg中的“外部碎片”和“虚拟地址碎片”的区别是什么?

WinDbg报告受影响堆的堆统计信息如下:

Heap     Flags   Reserv  Commit  Virt   Free  List   UCR  Virt  Lock  Fast
                  (k)     (k)    (k)     (k) length      blocks cont. heap
04770000 00001002 1621948  94844 1608284  102    6  8068    6      2   L 

  Virtual address fragmentation  94 % (8068 uncommited ranges)

没有分页文件对堆栈损坏或碎片化完全没有影响。这篇 KB 文章 很好地介绍了 LFH。 - Hans Passant
1个回答

4
与 Linux 不同,在 Windows 上,分配是一种承诺。您能够写入已分配的内存。性能可能非常差,但 Windows 不需要 OOM 消息。
如果没有页面文件,则必须使用 RAM 支持承诺。然而,未使用的存储器(例如仅在程序初始化期间使用的存储器)仍在使用 RAM,因为它无法进行分页。因此,可供承诺的 RAM 较少,但需要更大。
LFH 打破了有缺陷的程序,或更确切地说:有缺陷的程序可能会在 LFH 存在时显示其缺陷。微软对有问题的程序非常友好,并使 XP 中的 LFH 成为选择加入的典型示例。

Linux可以在没有内存超额提交的情况下运行。通常不这样做是因为在使用1GB RAM的进程中调用fork()会立即需要另外1GB的RAM。 - Zan Lynx
这是否意味着上述堆栈统计中的Reserv(k)金额1621948将占用相应数量的物理RAM?还是仅适用于Commit值? - Matt C

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接