我无法找到一个令人满意的解释,为什么在大型非托管分配之前调用GC.Collect(在我的情况下,在创建大型(~250Mb)DirectX资源之前)阻止了内存不足异常。为什么托管堆的压缩允许非托管分配?
.Net进程如何在托管和非托管堆之间共享其地址空间?
我最好的猜测是.Net进程在两种类型的堆和GC之间保持可移动的边界.Collect允许该边界移动以支持更大的非托管堆。像这样:
场景#1 - 没有GC.Collect
要进行非托管分配3个块,托管堆碎片化:
0123456789
MMFFMFFMFU
"高水位"托管堆在7
分配3个非托管块 - 失败! 注意托管堆的高水位标记不会为非托管分配留下空间。
场景#2 - 使用GC.Collect
即将进行3个块的非托管分配,托管堆碎片
0123456789
MMFFMFFMFU
"高水位"托管堆在7
调用GC.Collect
0123456789
MMMMFFFFFU
"高水位"托管堆在3
分配3个非托管块 - 成功!
0123456789
MMMMFFUUUU
这是如何运作的?