为什么托管堆的碎片会影响非托管堆分配请求的成功?

时间:2015-09-18 11:18:05

标签: c# garbage-collection unmanaged-memory

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

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

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

  • (M)已分配的分配
  • (U)nmanaged allocation
  • (F)ree memory
  • 处理地址空间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

这是如何运作的?

0 个答案:

没有答案