When allocating with the new keyword, does the CLR ever throttle via a Sleep statement when memory is low?(当使用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是否会通过睡眠语句进行限制?
基础教程推荐
- 将 Office 安装到 Windows 容器 (servercore:ltsc2019) 失败,错误代码为 17002 2022-01-01
- 将 XML 转换为通用列表 2022-01-01
- 为什么Flurl.Http DownloadFileAsync/Http客户端GetAsync需要 2022-09-30
- rabbitmq 的 REST API 2022-01-01
- 如何在 IDE 中获取 Xamarin Studio C# 输出? 2022-01-01
- 如何激活MC67中的红灯 2022-01-01
- MS Visual Studio .NET 的替代品 2022-01-01
- 有没有办法忽略 2GB 文件上传的 maxRequestLength 限制? 2022-01-01
- SSE 浮点算术是否可重现? 2022-01-01
- c# Math.Sqrt 实现 2022-01-01