.NET 托管堆何时以及如何进行交换?

发布于 2024-10-12 10:11:14 字数 542 浏览 11 评论 0原文

我的小型压力测试在循环中分配随机长度数组(每个 100..200MB),在 64 位 Win7 机器和 32 位 XP(在虚拟机中)上显示出不同的行为。两个系统通常首先分配适合 LOH 的尽可能多的数组。然后LOH会变得越来越大,直到可用的虚拟地址空间被填满。到目前为止的预期行为。但是,在进一步的请求中,两者的行为有所不同:

在 Win7 上,会抛出 OutOfMemoryException (OOM),而在 XP 上,堆似乎会增加,甚至交换到磁盘 - 至少不会抛出 OOM。 (不知道,这是否与在虚拟机中运行的 XP 有关。)

问题: 运行时(或操作系统?)如何决定,对于托管内存分配请求,是否太大而无法分配,是否会生成 OOM,或者大对象堆正在增加 - 最终甚至交换到磁盘? 如果交换的话什么时候会发生OOM?

在我看来,这个问题对于所有生产环境都很重要,可能会处理更大的数据集。不知何故,知道系统宁愿在这种情况下(通过交换)显着减慢速度,也不愿简单地抛出 OOM,这感觉更“安全”。至少,它应该是确定性的,对吗?

@Edit:该应用程序是32位应用程序,因此在Win 7上以32位模式运行。

My small stress test, which allocates random length arrays (100..200MB each) in a loop, shows different behaviour on a 64 bit Win7 machine and on a 32 bit XP (in a VM). Both systems first normally allocate as much arrays as will fit into the LOH. Then the LOH gets bigger and bigger until the virtual address space available is filled up. Expected behaviour so far. But than - on further requests - both behave differently:

While on Win7 an OutOfMemoryException (OOM) is thrown, on XP it seems, the heap gets increased and even swapped to disk - at least no OOM is thrown. (Dont know, if this may have to do with XP running in a virtual box.)

Question:
How does the runtime (or the OS?) decide, whether for managed memory allocation requests, if it is too large to get allocated, a OOM is generated or the large object heap is getting increased - eventually even swapped to disk?
If it is swapped, when does an OOM occour than?

IMO this question is important to all production environments, potentially dealing with larger datasets. Somehow it feels more "safe" to know, the system would rather slow down dramatically in such situations (by swapping) than simply throwing an OOM. At least, it should somehow be deterministically, right?

@Edit: the app is a 32 bit application, therefore running in 32 bit mode on Win 7.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

神经暖 2024-10-19 10:11:14

应用正常规则,Windows 内存管理器不会以不同方式对待托管进程。内存块的最终来源是 Windows 内存管理器。如果无法在虚拟内存地址空间中找到适合请求的内存分配的空位,则 VirtualAlloc() 调用将失败,并且 CLR 会生成 OOM。

交换行为也是如此,如果需要 RAM 中的页面来映射其他进程的页面,甚至同一进程的页面,那么它们将被换出。这与 OOM 没有其他关联。

您不能假设它在 XP 上的工作方式与在 Win7 x64 上的工作方式完全相同。当您构建针对 AnyCPU 的程序时,在 x64 上出现 OOM 是很不寻常的,64 位操作系统具有非常大的虚拟内存地址空间。上限由页面文件的最大大小设置。 32位程序将在WOW模拟层中运行,如果使用Editbin.exe设置LARGEADDRESSAWARE选项位,它可以拥有4GB地址空间。

您可以使用 SysInteral 的 VMMap 实用程序来查看进程的地址空间是如何划分的。

The normal rules apply, a managed process is not treated differently by the Windows memory manager. The ultimate source for chunks of memory is the Windows memory manager. If it cannot find a hole in the virtual memory address space to fit the requested memory allocation then it fails the VirtualAlloc() call and the CLR generates OOM.

Same for swapping behavior, if pages in RAM are needed to map pages of other processes or even pages of the same process then they'll get swapped out. This is not otherwise associated with OOM.

You cannot assume it will work exactly the same on XP as it does on Win7 x64. Getting OOM on x64 when you build your program targeting AnyCPU is quite unusual, a 64-bit operating system has a very large virtual memory address space. The upper limit is set by the maximum size of the paging file. A 32-bit program will run in the WOW emulation layer, it can have a 4 GB address space if you set the LARGEADDRESSAWARE option bit with Editbin.exe.

You can use SysInteral's VMMap utility to see how the address space of your process is carved up.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文