2013-02-20 46 views
9

在捕获EOutOfMemory异常之后继续执行还是现在堆或堆被破坏的概率很高?EOutOfMemory异常是否可恢复?

我不引起先前内存损坏EOutOfMemory的情况下是指由于喜欢写野生地址错误,我的意思是正确的代码调用GetMem和捕捉EOutOfMemory

+0

有时候是这样。我看到有人试图在Win32应用程序中分配3GB内存缓冲区:-) 因此,这取决于您在获取错误之前真正尝试执行的操作。在某些情况下可以恢复。 – 2013-02-21 06:08:25

回答

6

在我看来,从EOutOfMemory继续尝试是没有意义的。根据我的经验,堆的可能性非常高,将会损坏堆,并且可能会出现未来的错误。通常,最安全的做法是终止程序。

+0

我怀疑它不可恢复,但我不确定。我不知道FastMM的内部和Windows内存管理。 – kludg 2013-02-20 09:28:12

+1

在我们的服务器中,我们要求在EOutOfMemory上发布的初始化内存中存储内存,以便在我们终止进程之前异常和其他日志记录有一定的机动余地。 – 2013-02-20 09:49:00

+0

@MarjanVenema这也是有风险的,至少如果你的其他代码要使用损坏的堆。请注意,Delphi RTL在启动时分配单个'EOutOfMemory'实例,以便它不需要执行堆分配以提升异常。 – 2013-02-20 09:50:55

1

一般来说,我同意试图恢复是没有意义的。但在特定情况下它可能会有用。例如,分配大量依赖于用户选择的内存,如果失败,则可以干净地退出并让它们以不同的设置重试。我这样做是为了将点云转换为3D网格,其中包括一些预先不知道内存需求的步骤。它只需要仔细编制您想要恢复的步骤,并使用即时和干净的退出路径。例如,我的一些数据结构是位图或缓冲区,每行分别分配以最小化碎片内存问题。构造函数尝试...除了处理并抛出EOutOfMemory异常,并且析构函数释放已分配的任何行。我不能保证它会一直工作,但它已经运行得很好,值得去做。