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

When allocating with the new keyword, does the CLR ever throttle via a Sleep statement when memory is low?(当使用new关键字进行分配时,当内存不足时,CLR是否会通过睡眠语句进行限制?)

本文介绍了当使用new关键字进行分配时,当内存不足时,CLR是否会通过睡眠语句进行限制?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在堆栈溢出上遇到this answer此处:

当您分配的速度快于垃圾收集速度时,您将遇到OOM。如果您执行大量分配,CLR将插入睡眠(Xx)来限制分配,但在极端情况下这是不够的。

所以,我还没有读到任何关于CLR通过在内存不足时插入一条睡眠语句来减慢分配速度来限制分配的内容。有谁能证实这是真的还是假的?如果这是真的,那么有什么文件谈到了细节吗?我试过在谷歌上搜索,但找不到任何支持这一说法的东西。

推荐答案

非常感谢@AloisKrausresearch, patience, and links给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

为回答@Enigmative,GCToOSInterfaceSept方法定义为:

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

这位于gcenv.windows.cpp。

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

这篇关于当使用new关键字进行分配时,当内存不足时,CLR是否会通过睡眠语句进行限制?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本文标题为:当使用new关键字进行分配时,当内存不足时,CLR是否会通过睡眠语句进行限制?

基础教程推荐