gpt4 book ai didi

c# - 托管堆 OutOfMemory

转载 作者:行者123 更新时间:2023-11-30 16:58:37 25 4
gpt4 key购买 nike

编辑:我将其重新表述为问题并将答案移至答案部分...

在一个相对复杂的多线程 .NET 应用程序中,我遇到了 OutOfMemoryException,即使在我认为没有理由的情况下也是如此。

情况:

  • 应用程序是 32 位的。
  • 该应用程序创建了许多(数千个)被认为很小(小于大约 85kB)的短期对象。
  • 此外,它还会创建一些(数百个)被认为是大型(大于约 85kb)的短期对象。这意味着这些对象是在 LOH(大对象堆)中分配的。
  • 这些对象的两个类都定义了终结器 (~MyFinalizer(){...})。

症状:

  • OutOfMemoryException
  • 通过内存分析器查看应用程序,有数千个小对象符合收集条件,但未被收集,因此阻塞了大量内存。

问题:

  • 为什么应用会耗尽整个堆?
  • 为什么内存中仍然存在大量“死”对象?

最佳答案

经过深入调查,我找到了原因。由于花费了一些时间,我想让其他遇到同样问题的人也能轻松一些。

原因:

  • 应用只有大约 2GB 的虚拟地址空间。
  • LOH 在设计上并未压缩,因此可能会很快碎片化,但对于上述大对象的数量,这应该不是任何问题。
  • 由于垃圾收集器的设计,如果有定义终结器的对象(即使是空的),它会被视为 Gen2 对象并放入 GC 的终结队列中。这意味着,在完成之前(调用 MyFinalizer)它只会阻塞内存。在上述应用的情况下,运行终结器的 GC 线程没有机会尽快完成其工作,因此堆已耗尽。

解决方案:

不要对此类“动态”对象(高容量、短生命周期)使用终结器,以其他方式解决终结代码...

非常有用的资源:

关于c# - 托管堆 OutOfMemory,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25033335/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com