这个问题与我之前的问题 线程开销有关
既然Thread.Start
不要求线程运行的内存,为什么它会抛出OutOfMemoryException
?
下面是在 CLR 中启动托管线程的部分源代码:
CExecutionEngine::SetupTLSForThread(pThread);
if (!pThread->InitThread(fInternal) ||
!pThread->PrepareApartmentAndContext())
ThrowOutOfMemory();
if (UnsafeTlsSetValue(gThreadTLSIndex, (VOID*)this) == 0)
{
ThrowOutOfMemory();
}
if (UnsafeTlsSetValue(GetAppDomainTLSIndex(), (VOID*)m_pDomain) == 0)
{
ThrowOutOfMemory();
}
当然看起来它在很多情况下都会导致内存不足;如果无法初始化线程,如果无法准备单元或上下文,或者无法分配线程本地存储,则抛出“内存不足”。
在我看来,这是一个坏主意;我更愿意为“我试图分配一个新的虚拟内存块但找不到所需大小的块”的情况保留“内存不足”。诸如没有可用的 TLS 插槽或线程初始化失败之类的事情会导致内存不足,这只会令人困惑。
尽管仅在线程实际启动时才声明线程的堆栈,但注册线程以执行仍会占用一些内存,因此可能导致 OutOfMemoryException。
我觉得你搞错了。线程确实需要内存才能启动。每个线程都有它的own stack
,own stackpointer
等,必须为其保留内存。如果你碰巧没有足够的内存,exception
就会抛出一个。