15

这个问题与我之前的问题 线程开销有关

既然Thread.Start不要求线程运行的内存,为什么它会抛出OutOfMemoryException

4

3 回答 3

23

下面是在 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 插槽或线程初始化失败之类的事情会导致内存不足,这只会令人困惑。

于 2013-04-03T15:21:48.060 回答
4

尽管仅在线程实际启动时才声明线程的堆栈,但注册线程以执行仍会占用一些内存,因此可能导致 OutOfMemoryException。

于 2013-04-03T14:05:42.470 回答
0

我觉得你搞错了。线程确实需要内存才能启动。每个线程都有它的own stack,own stackpointer等,必须为其保留内存。如果你碰巧没有足够的内存,exception就会抛出一个。

于 2013-04-03T14:07:15.493 回答