使用 new 关键字进行分配时,CLR 是否会在内存不足时通过 Sleep 语句进行限制?

When allocating with the new keyword, does the CLR ever throttle via a Sleep statement when memory is low?

我在 Stack Overflow 上看到 this answer

当分配速度快于垃圾收集速度时,您将 运行 陷入 OOM。如果你进行大量分配,CLR 将插入一个 Sleep(xx) 来限制分配,但这在你的极端情况下是不够的。

所以,我没有读到任何有关 CLR 节流分配的信息,方法是在内存不足时插入 Sleep 语句来减慢分配速度。任何人都可以确认这是不是真的?如果是真的,那么有没有任何文件谈及细节?我已尝试进行 Google 搜索,但找不到任何支持此声明的内容。

非常感谢@AloisKraus research, patience, and links to the code in GC.cpp 在方法 gc_heap::allocate_small:

中显示了以下代码
#if defined (BACKGROUND_GC) && !defined (MULTIPLE_HEAPS)
    if (recursive_gc_sync::background_running_p())
    {
        background_soh_alloc_count++;
        if ((background_soh_alloc_count % bgc_alloc_spin_count) == 0)
        {
            add_saved_spinlock_info (false, me_release, mt_alloc_small);
            leave_spin_lock (&more_space_lock_soh);
            bool cooperative_mode = enable_preemptive();
            GCToOSInterface::Sleep (bgc_alloc_spin);
            disable_preemptive (cooperative_mode);
            enter_spin_lock (&more_space_lock_soh);
            add_saved_spinlock_info (false, me_acquire, mt_alloc_small);
        }
        else
        {
            //GCToOSInterface::YieldThread (0);
        }
    }
#endif //BACKGROUND_GC && !MULTIPLE_HEAPS

关键一行是:

GCToOSInterface::Sleep (bgc_alloc_spin);

bgc_alloc_spin 被初始化为 2,因此这会导致线程休眠 2 毫秒 (ms)。该代码每调用 140 次仅执行一次,并且仅在发生后台 GC 时执行。但是,这仍然足以导致 14,000 多个线程在 1 秒内休眠 2 毫秒,这将对性能产生重大影响(请参阅 Alois Kraus 的简单数学讨论)。

编辑 1

在回答@Enigmativity 时,GCToOSInterfaceSleep 方法定义为:

void GCToOSInterface::Sleep(uint32_t sleepMSec)
{
    ::Sleep(sleepMSec);
}        

这位于 gcenv.windows.cpp

总之,我提出的问题的答案是肯定的,当后台 GC 为 运行 时,CLR 会限制分配。限制分配的基本原理似乎是允许后台 GC 更快更有效地完成其工作。