MemoryFailPoint (MSDN)“在执行操作之前检查是否有足够的内存资源。”

但是实际上如何正确使用呢?

MemoryFailPoint是否为我创建的下一个大对象自动保留一些内存?还是只是检查内存是否空闲而不保留它?

它是否检查物理内存,物理内存以及页面文件,虚拟地址空间或其他全部内容?

我什么时候处理?在实际创建需要大量内存的对象之前,是否需要处理MemoryFailPoint?还是必须在处理MemoryFailPoint之前创建对象?

例如

try
{
   using (MemoryFailPoint mem = new MemoryFailPoint(500))
   {
      // allocate big object here?
   }
}
catch (InsufficientMemoryException e)
{
   // ...
}
// or allocate big object here?

// or allocate big object on another thread?


同一进程中的另一个线程可以窃取我用MemoryFailPoint保留的内存,还是MemoryFailPoint专门为当前线程保留内存?

如果不处理MemoryFailPoint,会发生什么?未处置的MemoryFailPoint本身是否会消耗大量内存?

最佳答案

MemoryFailPoint的源代码可从.NET Source获得。在课程开始时,描述性很强的评论回答了您的问题。我在这里复制该评论以便于参考:


  此类允许应用程序在启动某些应用程序之前失败
     活动。这个想法是尽早失败而不是在中间失败
     一些长期运行的操作以提高设备的生存能力
     应用程序,并确保您无需编写棘手的代码即可处理
     在应用程序代码中的任何位置均会发生OOM(这意味着状态损坏,这意味着您
     如果您有交易环境,应卸载appdomain,以确保
     单个交易的回滚)。这是尝试使用的不完整工具
     将所有OOM故障从工作人员方法中的任何地方提升到一个
     可以更容易地处理OOM故障的特定点,并且您可以
     如果可能会失败,可以选择选择不启动工作项。这确实
     无法直接帮助您提高代码的性能(除了有助于避免
     广告卸载)。关键是要避免可能失败的工作。
     企业服务团队有效地使用了这些内存门。
     十年来不受管理的世界。
  
  在Whidbey中,我们将简单地检查是否有足够的可用内存
     在操作系统的页面文件中并尝试确保可能有足够的可用空间
     在进程的地址空间内(检查地址空间是否碎片)
     以及)。我们不会提交或保留任何内存。为了避免---- s与
     其他使用MemoryFailPoints的线程,我们还将跟踪
     通过所有当前活动的“保留”的进程范围的内存量
     MemoryFailPoints。这有两个问题:

 1. This can account for memory twice.  If a thread creates a
     MemoryFailPoint for 100 MB then allocates 99 MB, we'll see 99 MB
     less free memory and 100 MB less reserved memory.  Yet, subtracting
     off the 100 MB is necessary because the thread may not have started
     allocating memory yet.  Disposing of this class immediately after
     front-loaded allocations have completed is a great idea.
 2. This is still vulnerable to ----s with other threads that don't use
     MemoryFailPoints.

  
  因此,该课程远非完美。但这可能足以
     有意义地减少托管应用程序中OutOfMemoryExceptions的频率。
  
  在Orcas或更高版本中,我们可能会从OS分配一些内存并添加它
     分配给该线程的分配上下文。显然,那时我们需要
     释放此内存块时的某种传达方式。所以,我们
     在Whidbey中对此类型实施了IDisposable,并希望所有用户都可以致电
     这是在using块中提供的,以为其记忆提供词汇范围
     用法。对Dispose的调用(与using块隐式关联)将为我们提供
     有机会释放这种记忆,也许。我们预计这将给
     我们有可能在未来的版本中进行更有效的设计。
  
  在逆戟鲸中,我们可能还需要区分将
     进入普通托管堆还是大型对象堆,否则我们应该
     考虑在两个位置检查是否有足够的可用空间(包括
     适当的调整以确保内存是连续的)。

10-08 03:46