windows 发生内存不足错误时怎么办?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3644381/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 15:11:35  来源:igfitidea点击:

What to do when an out-of-memory error occurs?

c++windowserror-handlingout-of-memory

提问by dyp

Possible Duplicate:
What's the graceful way of handling out of memory situations in C/C++?

可能的重复:
在 C/C++ 中处理内存不足情况的优雅方式是什么?

Hi,

你好,

this seems to be a simple question a first glance. And I don't want to start a huge discussion on what-is-the-best-way-to-do-this....

乍一看,这似乎是一个简单的问题。而且我不想就什么是最好的方法进行大量讨论......

Context: Windows >= 5, 32 bit, C++, Windows SDK / Win32 API

上下文:Windows >= 5,32 位,C++,Windows SDK / Win32 API

But after asking a similar question, I read some MSDN and about the Win32 memory management, so now I'm even more confused on what to do if an allocation fails, let's say the C++ new operator.

但是在问了一个类似的问题之后,我阅读了一些 MSDN 和有关 Win32 内存管理的内容,所以现在我对分配失败时该怎么办更加困惑,比如说 C++ new 运算符。

So I'm very interested now in how youimplement (and implicitly, if you do implement) an error handling for OOM in your applications.
If, where(main function?), for which operations(allocations) , and how you handle an OOM error.

所以我现在对如何在你的应用程序中为 OOM 实现(隐式,如果你实现)错误处理非常感兴趣。
If, where(main function?) , for which operations(allocations) ,以及如何处理 OOM 错误。

(I don't really mean that subjectively, turning this into a question of preference, I just like to see different approaches that account for different conditions or fit different situations. So feel free to offer answers for GUI apps, services - user-mode stuff ....)

(我并不是主观上的意思,把这变成一个偏好问题,我只是喜欢看到不同的方法来解释不同的条件或适合不同的情况。所以请随意提供 GUI 应用程序、服务的答案 - 用户模式东西 ....)

Some exemplary reactions to OOM to show what I mean:

对 OOM 的一些示例性反应来说明我的意思:

  • GUI app: Message box, exit process
  • non-GUI app: Log error, exit process
  • service: try to recover, e.g. kill the thread that raised an exception, but continue execution
  • critical app: try again until an allocation succeeds (reducing the requested amount of memory)
  • hands from OOM, let STL / boost / OS handle it
  • GUI app:消息框,退出流程
  • 非 GUI 应用程序:记录错误,退出过程
  • 服务:尝试恢复,例如杀死引发异常的线程,但继续执行
  • 关键应用程序:重试直到分配成功(减少请求的内存量)
  • 来自OOM的手,让STL/boost/OS来处理

Thank you for your answers!

谢谢您的回答!

The best-explained way will receive the great honour of being an accepted answer:D - even if it only consists of a MessageBox line, but explains why evering else was useless, wrong or unneccessary.

Edit: I appreciate your answers so far, but I'm missing a bit of an actual answer; what I mean is most of you say don't mind OOM since you can't do anything when there's no memory left (system hangs / poor performance). But does that mean to avoid any error handling for OOM? Or only do a simple try-catch in the main showing a MessageBox?

最好解释的方法将获得被接受的答案的巨大荣誉:D - 即使它只包含一个 MessageBox 行,但解释了为什么其他方法是无用的、错误的或不必要的。

编辑:到目前为止,我感谢您的回答,但我缺少一些实际答案;我的意思是,你们中的大多数人都说不要介意 OOM,因为当没有剩余内存(系统挂起/性能不佳)时,您将无法做任何事情。但这是否意味着要避免对 OOM 进行任何错误处理?或者只在显示 MessageBox 的主要部分做一个简单的 try-catch ?

回答by Hans Passant

You do the exact same thing you do when:

在以下情况下,您会做完全相同的事情:

  • you created 10,000 windows
  • you allocated 10,000 handles
  • you created 2,000 threads
  • you exceeded your quota of kernel pool memory
  • you filled up the hard disk to capacity.
  • 您创建了 10,000 个窗口
  • 您分配了 10,000 个句柄
  • 您创建了 2,000 个线程
  • 你超出了内核池内存的配额
  • 你把硬盘填满了。

You send your customer a very humble message where you apologize for writing such crappy code and promise a delivery date for the bug fix. Any else is not nearly good enough. How you want to be notified about it is up to you.

您向您的客户发送了一条非常谦虚的信息,为编写如此糟糕的代码而道歉,并承诺修复错误的交付日期。任何其他都不够好。您希望如何收到通知取决于您。

回答by Marcelo Cantos

On most modern OSes, OOM will occur long after the system has become completely unusable, since before actually running out, the virtual memory system will start paging physical RAM out to make room for allocating additional virtual memory and in all likelihood the hard disk will begin to thrash like crazy as pages have to be swapped in and out at higher and higher frequencies.

在大多数现代操作系统上,OOM 会在系统完全无法使用后很久才会发生,因为在实际用完之前,虚拟内存系统将开始分页物理 RAM 以腾出空间来分配额外的虚拟内存,并且硬盘很可能会启动因为页面必须以越来越高的频率换入和换出,所以像疯了一样颠簸。

In short, you have much more serious concerns to deal with before you go anywhere near OOM conditions.

简而言之,在接近 OOM 条件之前,您需要处理更多严重的问题。

Side note: At the moment, the above statement isn't as true as it used to be, since 32-bit machines with loads of physical RAM can exhaust their address space before they start to page. But this is still not common and is only temporary, as 64-bit ramps up and approaches mainstream adoption.

旁注:目前,上述陈述不像以前那样真实,因为具有大量物理 RAM 的 32 位机器可能会在开始分页之前耗尽它们的地址空间。但这仍然不常见,而且只是暂时的,因为 64 位正在上升并接近主流采用。

Edit: It seems that 64-bit is already mainstream. While perusing the Dell web site, I couldn't find a single 32-bit system on offer.

编辑:看来 64 位已经是主流了。在仔细阅读戴尔网站时,我找不到提供的单个 32 位系统。

回答by supercat

Basically, you should do whatever you can to avoid having the user lose important data. If disk space is available, you might write out recovery files. If you want to be super helpful, you might allocate recovery files while your program is open, to ensure that they will be available in case of emergency.

基本上,您应该尽一切努力避免用户丢失重要数据。如果磁盘空间可用,您可以写出恢复文件。如果您想成为超级有用的人,您可以在程序打开时分配恢复文件,以确保它们在紧急情况下可用。

回答by Joe D

Simply display a message or dialog box (depending on whether your in a terminal or window system), saying "Error: Out of memory", possibly with debugging info, and include an option for your user to file a bug report, or a web link to where they can do that.

只需显示一条消息或对话框(取决于您是在终端还是窗口系统中),说“错误:内存不足”,可能带有调试信息,并包含一个选项供您的用户提交错误报告或 Web链接到他们可以做到的地方。

If your really out of memory then, in all honesty, there's no point doing anything other than gracefully exiting, trying to handle the error is useless as there is nothing you can do.

如果你真的内存不足,老实说,除了优雅地退出之外,做任何事情都没有意义,尝试处理错误是没有用的,因为你无能为力。

回答by gbjbaanb

In my case, what happens when you have an app that fragments the memory up so much it cannot allocate the contiguous block needed to process the huge amount of nodes?

就我而言,当您有一个应用程序将内存碎片化得如此之多以至于无法分配处理大量节点所需的连续块时,会发生什么?

Well, I split the processing up as much as I could.

好吧,我尽可能地将处理分开。

For OOM, you can do the same thing, chop your processes up into as many pieces as possible and do them sequentially.

对于 OOM,您可以做同样的事情,将您的流程分成尽可能多的部分,然后按顺序执行。

Of course, for handling the error until you get to fix it (if you can!), you typically let it crash. Then you determine that those memory allocs are failing (like you never expected) and put a error message direct to the user along the lines of "oh dear, its all gone wrong. log a call with the support dept". In all cases, you inform the user however you like. Though, its established practice to use whatever mechanism the app currently uses - if it writes to a log file, do that, if it displays an error dialog, do the same, if it uses the Windows 'send info to microsoft' dialog, go right ahead and let that be the bearer of bad tidings - users are expecting it, so don't try to be clever and do something else.

当然,为了处理错误直到您修复它(如果可以的话!),您通常会让它崩溃。然后,您确定这些内存分配失败(就像您从未预料到的那样)并直接向用户发送一条错误消息,内容为“哦,亲爱的,一切都出错了。记录与支持部门的电话”。在所有情况下,您都可以根据自己的喜好通知用户。但是,它的既定做法是使用应用程序当前使用的任何机制 - 如果它写入日志文件,请执行此操作,如果它显示错误对话框,则执行相同操作,如果它使用 Windows 的“将信息发送到 microsoft”对话框,请执行就在前面,让它成为坏消息的承载者 - 用户正在期待它,所以不要试图变得聪明并做其他事情。

回答by James

It depends on your app, your skill level, and your time. If it needs to be running 24/7 then obviously you must handle it. It depends on the situation. Perhaps it may be possible to try a slower algorithm but one that requires less heap. Maybe you can add functionality so that if OOM does occur your app is capable of cleaning itself up, and so you can try again.

这取决于您的应用程序、您的技能水平和您的时间。如果它需要 24/7 全天候运行,那么显然您必须处理它。这取决于实际情况。也许可以尝试一种较慢但需要较少堆的算法。也许您可以添加功能,以便在确实发生 OOM 时您的应用程序能够自行清理,这样您就可以重试了。

So I think the answer is 'ALL OF THE ABOVE!', apart from LET IT CRASH. You take pride in your work, right?

所以我认为答案是“以上所有!”,除了让它崩溃。你为自己的工作感到自豪,对吧?

Don't fall into the 'there's loads of memory so it probably won't happen' trap. If every app writer took that attitude you'd see OOM far more often, and not all apps are running on a desktop machines, take a mobile phone for example, it's highly likely for you to run into OOM on a RAM starved platform like that, trust me!

不要落入“有大量内存,所以它可能不会发生”的陷阱。如果每个应用程序编写者都采取这种态度,您会更频繁地看到 OOM,并且并非所有应用程序都在台式机上运行,​​以手机为例,您很可能会在这样的 RAM 匮乏的平台上遇到 OOM , 相信我!

If all else fails display a useful message (assuming there's enough memory for a MessageBox!)

如果所有其他方法都失败了,则显示一条有用的消息(假设 MessageBox 有足够的内存!)