首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >动态内存分配故障恢复

动态内存分配故障恢复
EN

Stack Overflow用户
提问于 2008-12-15 02:02:48
回答 9查看 3.9K关注 0票数 6

我正在开发一款嵌入式处理器(400 MHz Intel PXA255 XScale),我想我看到了这样一种情况:内存不足,无法满足“新”操作的需要。程序没有崩溃,所以我认为其他线程已经释放了它们的内存,这只是一个短暂的事情。这是一些非常关键的代码,因此退出不是一个选项,需要将某种错误返回给远程用户。

下面的小修正是否足以解决问题,还是有更好的解决方法?在用下面的代码替换每一个“新”之前,我想我应该先问一下。

代码语言:javascript
复制
char someArr[];
do{ 
    someArr = new char[10]; 
    Sleep(100); // no justification for choosing 100 ms
} while ( someArr == NULL );

睡眠有帮助吗?我应该设置最大重试次数吗?在任何地方都可以使用静态初始化吗?

最终更新:非常感谢您的帮助响应,但是在检查失败内存分配的代码时出现了错误。我将记住所有这些答案,并尽可能多地替换malloc和new(特别是在错误处理代码中)。

EN

回答 9

Stack Overflow用户

回答已采纳

发布于 2008-12-28 08:00:56

有几种不同的攻击方法--注意,根据您使用的Windows / Windows版本,工具说明会有所不同。

一些需要回答的问题:

1.您的应用程序是否泄漏内存,从而导致内存不足?

2.您的应用程序是否在某些阶段使用过多的内存,从而导致内存不足?

可以使用Windows工具研究1和2,该工具可以为您的产品提供详细的内存日志工具。其他堆包装工具也可以提供类似的信息(可能更高性能),这取决于您的产品设计。

http://msdn.microsoft.com/en-us/library/aa446904.aspx

3.在此过程中是否经常分配和释放内存?

Windows CE,在OS版本6.0之前(不要与WindowsMobile6.x混淆)有32 of /进程虚拟内存限制,这往往会导致许多有趣的碎片问题。在这种情况下,即使您有足够的物理内存空闲,您可能会耗尽虚拟内存。使用自定义块分配器通常可以缓解此问题。

4.您是否分配非常大的内存块?(> 2MB)

与3相关的是,您可能会耗尽进程虚拟内存空间。有些技巧在一定程度上依赖于OS版本,在进程空间之外的共享VM空间中分配内存。如果您正在耗尽VM,但没有物理RAM,这可能会有所帮助。

5.您是否使用大量DLL?

也与3相关,取决于操作系统版本,DLL也可能很快地减少整个可用VM。

进一步跳槽:

CE内存工具概述

base/archive/2006/01/11/511883.aspx

目标控制窗口“mi”工具

http://msdn.microsoft.com/en-us/library/aa450013.aspx

票数 2
EN

Stack Overflow用户

发布于 2008-12-15 02:44:28

你正试图通过局部推理来解决一个全球性问题。全局问题是,整个设备为操作系统和所有应用程序拥有有限数量的RAM (可能还有后备存储)。为了确保不超过这一数量的RAM,您有以下几个选项:

  • 每个进程在一个固定数量的RAM中运行,每个进程在启动时被确定;程序员进行推理以确保一切都符合。因此,是的,可以静态地分配所有。这只是大量的工作,每次更改系统配置时,都必须重新考虑分配的
  • 进程知道自己的内存使用和需求,并不断地建议对方他们需要多少内存。他们合作,这样他们就不会失去记忆,。这假设系统中至少有一些进程可以调整自己的内存需求(例如,通过改变内部缓存的大小)。阿隆索和阿佩尔写了一个关于这种方法的论文
  • 每个进程都知道内存可能会耗尽,可能会失败到消耗最小内存的状态。通常,这种策略是通过内存不足的异常来实现的。异常在main()中或在main()附近处理,内存不足事件实际上从零开始重新启动程序。如果响应用户请求内存增长,则此故障转移模式可以工作;如果程序的内存需求与用户的操作无关,则会导致.崩溃。

您以上的建议与任何一种方案都不匹配,相反,您希望其他一些进程能够解决问题,并且您需要的内存最终会出现。你可能会很幸运。你可能不会。

如果您希望您的系统能够可靠地工作,那么您最好考虑到共享有限内存的需要,重新考虑在系统上运行的每个进程的设计。这可能比你预期的要大,但如果你明白问题所在,你就可以做到这一点。祝好运!

票数 16
EN

Stack Overflow用户

发布于 2008-12-15 03:31:16

在其他答案中有很多好的地方,但我认为值得补充的是,如果所有线程都处于类似的循环中,那么程序就会陷入僵局。

对这种情况的“正确”答案可能是对程序的不同部分有严格的限制,以确保它们不会过度消耗内存。这可能需要重写整个程序所有部分的主要部分。

下一个最好的解决方案是进行一些回调,其中失败的分配尝试可以告诉程序的其余部分需要更多的内存。也许程序的其他部分可以比通常更积极地释放一些缓冲区,或者释放用于缓存搜索结果的内存等等。这将需要为程序的其他部分编写新代码。但是,这可以逐步完成,而不需要对整个程序进行重写。

另一种解决方案是让程序用互斥锁保护大型(临时)内存请求。听起来你很有信心,如果你以后再试一次的话,内存很快就会释放。我建议您使用互斥锁进行可能消耗大量内存的操作,这将允许在另一个线程释放了所需内存时立即唤醒该线程。否则,即使内存立即释放,线程也会休眠十分之一秒。

您还可以尝试that (0),这将简单地将控制传递给任何准备运行的其他线程。这将使您的线程可以立即恢复控制,如果所有其他线程进入睡眠,而不是等待它的100毫秒的句子。但是,如果至少有一个线程还想运行,那么您仍然需要等待直到它放弃控制。据我所知,这通常是Linux机器上的10毫秒。我不知道其他平台。如果线程自愿进入休眠状态,则您的线程在调度程序中也可能具有较低的优先级。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/367310

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档