(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本身是否消耗大量内存?
发布于 2016-03-01 20:40:33
MemoryFailPoint的源代码可在.NET源上获得。课堂开始时的描述性评论回答了你的问题。为了便于参考,我在这里复制了这一评论:
该类允许应用程序在启动某些活动之前失败。这样做的想法是尽早失败,而不是在一些长期运行的操作中失败,以提高应用程序的生存能力,并确保您不必编写复杂的代码来处理应用程序代码中的任何位置的OOM (这意味着如果您有事务处理环境以确保单个事务的回滚,则应该卸载appdomain )。这是一个不完整的工具,可以尝试将所有OOM故障从工作方法中的任何位置提升到处理OOM故障更容易的一个特定点,如果某个工作项可能失败,您可以选择不启动它。这无助于直接提高代码的性能(除了帮助避免AD卸载之外)。关键是要避免开始工作,如果它有可能失败。 企业服务团队十年来一直有效地在非管理世界中使用这些内存门。 在Whidbey中,我们只需检查OS的页面文件中是否有足够的内存&尝试确保进程的地址空间中有足够的空闲空间(也检查地址空间碎片)。我们不会提交或保留任何记忆。为了避免-与使用MemoryFailPoints的其他线程发生冲突,我们还将通过所有当前活动的MemoryFailPoints跟踪整个进程范围内的“保留”内存。这有两个问题: 1.这可以解释两次内存。如果一个线程为100 MB创建一个MemoryFailPoint,然后分配99 MB,那么我们将看到99 MB的空闲内存和100 MB的保留内存。然而,减去100 MB是必要的,因为线程可能还没有开始分配内存。在前面加载的分配完成后立即处理这个类是一个好主意。2.这仍然容易-其他不使用MemoryFailPoints的线程。 所以这门课还远远不够完美。但是,它可能足够有效地减少管理应用程序中的OutOfMemoryExceptions频率。 在Orcas或更高版本中,我们可以从操作系统中分配一些内存,并将其添加到这个线程的分配上下文中。显然,当我们释放这个内存块时,我们需要某种方式来传递信息。因此,我们在Whidbey中对这种类型实现了IDisposable,并期望所有用户从using块中调用它,以便为他们的内存使用提供词法范围。调用Dispose (隐含在using块中)可能会给我们释放这个内存的机会。我们预计这将使我们有可能在未来的版本中进行更有效的设计。 在Orcas中,我们还可能需要区分进入正常托管堆和大对象堆的分配,或者我们应该考虑在这两个位置检查足够的空闲空间(进行任何适当的调整,以确保内存是连续的)。
发布于 2016-10-12 17:23:25
使用模式如下:
const int sizeMB = 500;
using (MemoryFailPoint mem = new MemoryFailPoint(sizeMB))
{
// Allocate sizeMB - large object here. The allocation is *likely* going to succeed.
}当MemoryFailPoint构造函数失败时,大对象分配抛出OOM的可能性很大。即使成功了,它也会使进程对其他(甚至更小)的内存分配操作不太稳定。
在我的16 GB Windows环境中,下面的示例比在数组分配代码中不使用InsufficientMemoryException (步骤=6)的情况下,比OOM早一次迭代(步骤= 5):
List<byte[]> arrays = new List<byte[]>();
const int size = int.MaxValue/2;
const int sizeMB = size / 1024 / 1024;
for(int step = 0; step < 10000; step++)
{
using (new MemoryFailPoint(sizeMB))
{
arrays.Add(new byte[size]);
}
}https://stackoverflow.com/questions/35731975
复制相似问题