1

对于为什么在大型非托管分配之前调用 GC.Collect (在我的情况下,在创建大型(~250Mb)DirectX 资源之前)可以防止内存不足异常,我无法找到令人满意的解释。为什么托管堆的压缩允许非托管分配?

.Net 进程如何在托管堆和非托管堆之间共享其地址空间?

我最好的猜测是 .Net 进程在两种类型的堆和 GC 之间保持可移动的边界。Collect 允许该边界移动以支持更大的非托管堆。像这样的东西:

  • (M)托管分配
  • (U)n 托管分配
  • (F) 自由记忆
  • 进程地址空间 0-9

场景 #1 – 没有 GC.Collect

即将进行 3 个块的非托管分配,托管堆碎片化:

0123456789
MMFFMFFMFU

托管堆的“高水位标记”为 7

分配 3 个非托管块 -失败! 请注意,托管堆的高水位标记没有为非托管分配留下空间。

场景 #2 – 使用 GC.Collect

即将进行 3 个块的非托管分配,托管堆碎片化

0123456789
MMFFMFFMFU

托管堆的“高水位标记”为 7

调用 GC.Collect

0123456789
MMMMFFFFFU

托管堆的“高水位标记”为 3

分配 3 个非托管块 –成功!

0123456789
MMMMFFUUUU

这是它的工作原理吗?

4

0 回答 0