【问题标题】:Why Thread.Start can throw OutOfMemoryException为什么 Thread.Start 会抛出 OutOfMemoryException
【发布时间】:2013-04-03 23:21:48
【问题描述】:

这个问题和我之前的问题有关 Thread overhead

既然Thread.Start 没有为线程运行申请内存,为什么它会抛出OutOfMemoryException

【问题讨论】:

  • 你在线程中做什么?
  • 线程在做什么并不重要——这些东西会抛出它们自己的 OutOfMemoryExceptions——它们不会流回 thread.start。

标签: c# .net


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    虽然线程堆栈仅在线程实际启动时才被认领,但注册线程执行仍会占用一些内存,因此可能导致 OutOfMemoryException。

    【讨论】:

      【解决方案3】:

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

      【讨论】:

      • 您可能想阅读链接问题的答案。它声明堆栈仅在线程实际启动时才被声明。 Thread.Start 不这样做。它只是安排要启动的线程。
      • 可能,但你知道到底发生了什么吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-28
      相关资源
      最近更新 更多